LICENSE - Ruby 2.0.0-p576 Standard Library API Reference API Reference

Ruby 2.0.0-p576 Standard Library API Reference API Reference

This is the API documentation for 'Ruby 2.0.0-p576 Standard Library API Reference API Reference'.

Classes/Modules

  • RSS
  • RSS::Atom
  • RSS::Atom::CommonModel
  • RSS::Atom::ContentModel
  • RSS::Atom::ContentModel::ClassMethods
  • RSS::Atom::DateConstruct
  • RSS::Atom::DuplicateLinkChecker
  • RSS::Atom::Entry
  • RSS::Atom::Feed
  • RSS::Atom::Feed::Author
  • RSS::Atom::Feed::Category
  • RSS::Atom::Feed::Contributor
  • RSS::Atom::Feed::Entry
  • RSS::Atom::Feed::Entry::Content
  • RSS::Atom::Feed::Entry::Published
  • RSS::Atom::Feed::Entry::Source
  • RSS::Atom::Feed::Entry::Summary
  • RSS::Atom::Feed::Generator
  • RSS::Atom::Feed::Icon
  • RSS::Atom::Feed::Id
  • RSS::Atom::Feed::Link
  • RSS::Atom::Feed::Logo
  • RSS::Atom::Feed::Rights
  • RSS::Atom::Feed::Subtitle
  • RSS::Atom::Feed::Title
  • RSS::Atom::Feed::Updated
  • RSS::Atom::PersonConstruct
  • RSS::Atom::PersonConstruct::Email
  • RSS::Atom::PersonConstruct::Name
  • RSS::Atom::PersonConstruct::Uri
  • RSS::Atom::TextConstruct
  • RSS::Atom::URIContentModel
  • RSS::BaseDublinCoreModel
  • RSS::BaseListener
  • RSS::BaseModel
  • RSS::BaseParser
  • RSS::BaseTrackBackModel
  • RSS::ContentModel
  • RSS::ConversionError
  • RSS::Converter
  • RSS::DublinCoreModel
  • RSS::DublincoreModel
  • RSS::Element
  • RSS::Error
  • RSS::ITunesBaseModel
  • RSS::ITunesChannelModel
  • RSS::ITunesChannelModel::ITunesCategory
  • RSS::ITunesChannelModel::ITunesImage
  • RSS::ITunesChannelModel::ITunesOwner
  • RSS::ITunesItemModel
  • RSS::ITunesItemModel::ITunesDuration
  • RSS::ITunesModelUtils
  • RSS::ImageFaviconModel
  • RSS::ImageFaviconModel::ImageFavicon
  • RSS::ImageItemModel
  • RSS::ImageItemModel::ImageItem
  • RSS::ImageModelUtils
  • RSS::InvalidRSSError
  • RSS::ListenerMixin
  • RSS::Maker
  • RSS::Maker::Atom
  • RSS::Maker::Atom::Entry
  • RSS::Maker::Atom::Entry::Channel
  • RSS::Maker::Atom::Entry::Channel::Cloud
  • RSS::Maker::Atom::Entry::Channel::Description
  • RSS::Maker::Atom::Entry::Channel::Generator
  • RSS::Maker::Atom::Entry::Channel::SkipDays
  • RSS::Maker::Atom::Entry::Channel::SkipDays::Day
  • RSS::Maker::Atom::Entry::Channel::SkipHours
  • RSS::Maker::Atom::Entry::Channel::SkipHours::Hour
  • RSS::Maker::Atom::Entry::Image
  • RSS::Maker::Atom::Entry::Items
  • RSS::Maker::Atom::Entry::Items::Item
  • RSS::Maker::Atom::Entry::Textinput
  • RSS::Maker::Atom::Feed
  • RSS::Maker::Atom::Feed::Channel
  • RSS::Maker::Atom::Feed::Channel::Categories
  • RSS::Maker::Atom::Feed::Channel::Categories::Category
  • RSS::Maker::Atom::Feed::Channel::Cloud
  • RSS::Maker::Atom::Feed::Channel::Generator
  • RSS::Maker::Atom::Feed::Channel::Links
  • RSS::Maker::Atom::Feed::Channel::Links::Link
  • RSS::Maker::Atom::Feed::Channel::SkipDays
  • RSS::Maker::Atom::Feed::Channel::SkipDays::Day
  • RSS::Maker::Atom::Feed::Channel::SkipHours
  • RSS::Maker::Atom::Feed::Channel::SkipHours::Hour
  • RSS::Maker::Atom::Feed::Image
  • RSS::Maker::Atom::Feed::Items
  • RSS::Maker::Atom::Feed::Items::Item
  • RSS::Maker::Atom::Feed::Items::Item::Categories
  • RSS::Maker::Atom::Feed::Items::Item::Categories::Category
  • RSS::Maker::Atom::Feed::Items::Item::Content
  • RSS::Maker::Atom::Feed::Items::Item::Enclosure
  • RSS::Maker::Atom::Feed::Items::Item::Guid
  • RSS::Maker::Atom::Feed::Items::Item::Links
  • RSS::Maker::Atom::Feed::Items::Item::Links::Link
  • RSS::Maker::Atom::Feed::Items::Item::Source
  • RSS::Maker::Atom::Feed::Items::Item::Source::Categories
  • RSS::Maker::Atom::Feed::Items::Item::Source::Categories::Category
  • RSS::Maker::Atom::Feed::Items::Item::Source::Generator
  • RSS::Maker::Atom::Feed::Items::Item::Source::Icon
  • RSS::Maker::Atom::Feed::Items::Item::Source::Links
  • RSS::Maker::Atom::Feed::Items::Item::Source::Links::Link
  • RSS::Maker::Atom::Feed::Items::Item::Source::Logo
  • RSS::Maker::Atom::Feed::Textinput
  • RSS::Maker::AtomCategory
  • RSS::Maker::AtomGenerator
  • RSS::Maker::AtomLink
  • RSS::Maker::AtomLogo
  • RSS::Maker::AtomPersonConstructBase
  • RSS::Maker::AtomPersons
  • RSS::Maker::AtomTextConstruct
  • RSS::Maker::AtomTextConstructBase
  • RSS::Maker::AtomTextConstructBase::EnsureXMLContent
  • RSS::Maker::Base
  • RSS::Maker::ChannelBase
  • RSS::Maker::ChannelBase::AuthorsBase
  • RSS::Maker::ChannelBase::AuthorsBase::AuthorBase
  • RSS::Maker::ChannelBase::CategoriesBase
  • RSS::Maker::ChannelBase::CategoriesBase::CategoryBase
  • RSS::Maker::ChannelBase::CloudBase
  • RSS::Maker::ChannelBase::ContributorsBase
  • RSS::Maker::ChannelBase::ContributorsBase::ContributorBase
  • RSS::Maker::ChannelBase::CopyrightBase
  • RSS::Maker::ChannelBase::DescriptionBase
  • RSS::Maker::ChannelBase::GeneratorBase
  • RSS::Maker::ChannelBase::ITunesCategories
  • RSS::Maker::ChannelBase::ITunesCategories::ITunesCategory
  • RSS::Maker::ChannelBase::ITunesImage
  • RSS::Maker::ChannelBase::ITunesOwner
  • RSS::Maker::ChannelBase::LinksBase
  • RSS::Maker::ChannelBase::LinksBase::LinkBase
  • RSS::Maker::ChannelBase::SkipDaysBase
  • RSS::Maker::ChannelBase::SkipDaysBase::DayBase
  • RSS::Maker::ChannelBase::SkipHoursBase
  • RSS::Maker::ChannelBase::SkipHoursBase::HourBase
  • RSS::Maker::ChannelBase::TitleBase
  • RSS::Maker::ContentModel
  • RSS::Maker::DublinCoreModel
  • RSS::Maker::ITunesBaseModel
  • RSS::Maker::ITunesChannelModel
  • RSS::Maker::ITunesChannelModel::ITunesCategoriesBase
  • RSS::Maker::ITunesChannelModel::ITunesCategoriesBase::ITunesCategoryBase
  • RSS::Maker::ITunesChannelModel::ITunesImageBase
  • RSS::Maker::ITunesChannelModel::ITunesOwnerBase
  • RSS::Maker::ITunesItemModel
  • RSS::Maker::ITunesItemModel::ITunesDurationBase
  • RSS::Maker::ImageBase
  • RSS::Maker::ImageFaviconModel
  • RSS::Maker::ImageFaviconModel::ImageFaviconBase
  • RSS::Maker::ImageItemModel
  • RSS::Maker::ImageItemModel::ImageItemBase
  • RSS::Maker::ItemsBase
  • RSS::Maker::ItemsBase::ItemBase
  • RSS::Maker::ItemsBase::ItemBase::ContentBase
  • RSS::Maker::ItemsBase::ItemBase::DescriptionBase
  • RSS::Maker::ItemsBase::ItemBase::EnclosureBase
  • RSS::Maker::ItemsBase::ItemBase::GuidBase
  • RSS::Maker::ItemsBase::ItemBase::ITunesDuration
  • RSS::Maker::ItemsBase::ItemBase::RightsBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase::IconBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase::LogoBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase::RightsBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase::SubtitleBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase::TitleBase
  • RSS::Maker::ItemsBase::ItemBase::TitleBase
  • RSS::Maker::RSS09
  • RSS::Maker::RSS091
  • RSS::Maker::RSS091::Channel
  • RSS::Maker::RSS091::Image
  • RSS::Maker::RSS091::Items
  • RSS::Maker::RSS091::Items::Item
  • RSS::Maker::RSS091::Textinput
  • RSS::Maker::RSS092
  • RSS::Maker::RSS092::Channel
  • RSS::Maker::RSS092::Image
  • RSS::Maker::RSS092::Items
  • RSS::Maker::RSS092::Items::Item
  • RSS::Maker::RSS092::Textinput
  • RSS::Maker::RSS09::Channel
  • RSS::Maker::RSS09::Channel::Authors
  • RSS::Maker::RSS09::Channel::Authors::Author
  • RSS::Maker::RSS09::Channel::Categories
  • RSS::Maker::RSS09::Channel::Categories::Category
  • RSS::Maker::RSS09::Channel::Cloud
  • RSS::Maker::RSS09::Channel::Contributors
  • RSS::Maker::RSS09::Channel::Contributors::Contributor
  • RSS::Maker::RSS09::Channel::Copyright
  • RSS::Maker::RSS09::Channel::Description
  • RSS::Maker::RSS09::Channel::Generator
  • RSS::Maker::RSS09::Channel::Links
  • RSS::Maker::RSS09::Channel::Links::Link
  • RSS::Maker::RSS09::Channel::SkipDays
  • RSS::Maker::RSS09::Channel::SkipDays::Day
  • RSS::Maker::RSS09::Channel::SkipHours
  • RSS::Maker::RSS09::Channel::SkipHours::Hour
  • RSS::Maker::RSS09::Channel::Title
  • RSS::Maker::RSS09::Image
  • RSS::Maker::RSS09::Items
  • RSS::Maker::RSS09::Items::Item
  • RSS::Maker::RSS09::Items::Item::Authors
  • RSS::Maker::RSS09::Items::Item::Authors::Author
  • RSS::Maker::RSS09::Items::Item::Categories
  • RSS::Maker::RSS09::Items::Item::Categories::Category
  • RSS::Maker::RSS09::Items::Item::Content
  • RSS::Maker::RSS09::Items::Item::Contributors
  • RSS::Maker::RSS09::Items::Item::Contributors::Contributor
  • RSS::Maker::RSS09::Items::Item::Description
  • RSS::Maker::RSS09::Items::Item::Enclosure
  • RSS::Maker::RSS09::Items::Item::Guid
  • RSS::Maker::RSS09::Items::Item::Links
  • RSS::Maker::RSS09::Items::Item::Links::Link
  • RSS::Maker::RSS09::Items::Item::Rights
  • RSS::Maker::RSS09::Items::Item::Source
  • RSS::Maker::RSS09::Items::Item::Source::Authors
  • RSS::Maker::RSS09::Items::Item::Source::Authors::Author
  • RSS::Maker::RSS09::Items::Item::Source::Categories
  • RSS::Maker::RSS09::Items::Item::Source::Categories::Category
  • RSS::Maker::RSS09::Items::Item::Source::Contributors
  • RSS::Maker::RSS09::Items::Item::Source::Contributors::Contributor
  • RSS::Maker::RSS09::Items::Item::Source::Generator
  • RSS::Maker::RSS09::Items::Item::Source::Icon
  • RSS::Maker::RSS09::Items::Item::Source::Links
  • RSS::Maker::RSS09::Items::Item::Source::Links::Link
  • RSS::Maker::RSS09::Items::Item::Source::Logo
  • RSS::Maker::RSS09::Items::Item::Source::Rights
  • RSS::Maker::RSS09::Items::Item::Source::Subtitle
  • RSS::Maker::RSS09::Items::Item::Source::Title
  • RSS::Maker::RSS09::Items::Item::Title
  • RSS::Maker::RSS09::Textinput
  • RSS::Maker::RSS10
  • RSS::Maker::RSS10::Channel
  • RSS::Maker::RSS10::Channel::Authors
  • RSS::Maker::RSS10::Channel::Authors::Author
  • RSS::Maker::RSS10::Channel::Categories
  • RSS::Maker::RSS10::Channel::Categories::Category
  • RSS::Maker::RSS10::Channel::Cloud
  • RSS::Maker::RSS10::Channel::Contributors
  • RSS::Maker::RSS10::Channel::Contributors::Contributor
  • RSS::Maker::RSS10::Channel::Copyright
  • RSS::Maker::RSS10::Channel::Description
  • RSS::Maker::RSS10::Channel::Generator
  • RSS::Maker::RSS10::Channel::Links
  • RSS::Maker::RSS10::Channel::Links::Link
  • RSS::Maker::RSS10::Channel::SkipDays
  • RSS::Maker::RSS10::Channel::SkipDays::Day
  • RSS::Maker::RSS10::Channel::SkipHours
  • RSS::Maker::RSS10::Channel::SkipHours::Hour
  • RSS::Maker::RSS10::Channel::Title
  • RSS::Maker::RSS10::Image
  • RSS::Maker::RSS10::Items
  • RSS::Maker::RSS10::Items::Item
  • RSS::Maker::RSS10::Items::Item::Authors
  • RSS::Maker::RSS10::Items::Item::Authors::Author
  • RSS::Maker::RSS10::Items::Item::Categories
  • RSS::Maker::RSS10::Items::Item::Categories::Category
  • RSS::Maker::RSS10::Items::Item::Content
  • RSS::Maker::RSS10::Items::Item::Contributors
  • RSS::Maker::RSS10::Items::Item::Contributors::Contributor
  • RSS::Maker::RSS10::Items::Item::Description
  • RSS::Maker::RSS10::Items::Item::Enclosure
  • RSS::Maker::RSS10::Items::Item::Guid
  • RSS::Maker::RSS10::Items::Item::Links
  • RSS::Maker::RSS10::Items::Item::Links::Link
  • RSS::Maker::RSS10::Items::Item::Rights
  • RSS::Maker::RSS10::Items::Item::Source
  • RSS::Maker::RSS10::Items::Item::Source::Authors
  • RSS::Maker::RSS10::Items::Item::Source::Authors::Author
  • RSS::Maker::RSS10::Items::Item::Source::Categories
  • RSS::Maker::RSS10::Items::Item::Source::Categories::Category
  • RSS::Maker::RSS10::Items::Item::Source::Contributors
  • RSS::Maker::RSS10::Items::Item::Source::Contributors::Contributor
  • RSS::Maker::RSS10::Items::Item::Source::Generator
  • RSS::Maker::RSS10::Items::Item::Source::Icon
  • RSS::Maker::RSS10::Items::Item::Source::Links
  • RSS::Maker::RSS10::Items::Item::Source::Links::Link
  • RSS::Maker::RSS10::Items::Item::Source::Logo
  • RSS::Maker::RSS10::Items::Item::Source::Rights
  • RSS::Maker::RSS10::Items::Item::Source::Subtitle
  • RSS::Maker::RSS10::Items::Item::Source::Title
  • RSS::Maker::RSS10::Items::Item::Title
  • RSS::Maker::RSS10::Textinput
  • RSS::Maker::RSS20
  • RSS::Maker::RSS20::Channel
  • RSS::Maker::RSS20::Channel::Categories
  • RSS::Maker::RSS20::Channel::Categories::Category
  • RSS::Maker::RSS20::Channel::Cloud
  • RSS::Maker::RSS20::Channel::Generator
  • RSS::Maker::RSS20::Channel::SkipDays
  • RSS::Maker::RSS20::Channel::SkipDays::Day
  • RSS::Maker::RSS20::Channel::SkipHours
  • RSS::Maker::RSS20::Channel::SkipHours::Hour
  • RSS::Maker::RSS20::Image
  • RSS::Maker::RSS20::Items
  • RSS::Maker::RSS20::Items::Item
  • RSS::Maker::RSS20::Items::Item::Authors
  • RSS::Maker::RSS20::Items::Item::Authors::Author
  • RSS::Maker::RSS20::Items::Item::Categories
  • RSS::Maker::RSS20::Items::Item::Categories::Category
  • RSS::Maker::RSS20::Items::Item::Enclosure
  • RSS::Maker::RSS20::Items::Item::Guid
  • RSS::Maker::RSS20::Items::Item::Source
  • RSS::Maker::RSS20::Items::Item::Source::Links
  • RSS::Maker::RSS20::Items::Item::Source::Links::Link
  • RSS::Maker::RSS20::Textinput
  • RSS::Maker::RSSBase
  • RSS::Maker::SetupDefaultDate
  • RSS::Maker::SetupDefaultLanguage
  • RSS::Maker::SlashModel
  • RSS::Maker::SyndicationModel
  • RSS::Maker::TaxonomyTopicModel
  • RSS::Maker::TaxonomyTopicModel::TaxonomyTopicsBase
  • RSS::Maker::TaxonomyTopicModel::TaxonomyTopicsBase::TaxonomyTopicBase
  • RSS::Maker::TaxonomyTopicsModel
  • RSS::Maker::TaxonomyTopicsModel::TaxonomyTopicsBase
  • RSS::Maker::TextinputBase
  • RSS::Maker::TrackBackModel
  • RSS::Maker::TrackBackModel::TrackBackAboutsBase
  • RSS::Maker::TrackBackModel::TrackBackAboutsBase::TrackBackAboutBase
  • RSS::Maker::XMLStyleSheets
  • RSS::Maker::XMLStyleSheets::XMLStyleSheet
  • RSS::MissingAttributeError
  • RSS::MissingTagError
  • RSS::NSError
  • RSS::NotAvailableValueError
  • RSS::NotExceptedTagError
  • RSS::NotExpectedTagError
  • RSS::NotSetError
  • RSS::NotValidXMLParser
  • RSS::NotWellFormedError
  • RSS::OverlappedPrefixError
  • RSS::Parser
  • RSS::RDF
  • RSS::RDF::Bag
  • RSS::RDF::Bag::Li
  • RSS::RDF::Channel
  • RSS::RDF::Channel::Image
  • RSS::RDF::Channel::Items
  • RSS::RDF::Channel::Items::Seq
  • RSS::RDF::Channel::Textinput
  • RSS::RDF::Image
  • RSS::RDF::Item
  • RSS::RDF::Li
  • RSS::RDF::Seq
  • RSS::RDF::Seq::Li
  • RSS::RDF::Textinput
  • RSS::REXMLLikeXMLParser
  • RSS::REXMLListener
  • RSS::REXMLParser
  • RSS::RSS09
  • RSS::RSS10
  • RSS::RootElementMixin
  • RSS::Rss
  • RSS::Rss::Channel
  • RSS::Rss::Channel::Cloud
  • RSS::Rss::Channel::Image
  • RSS::Rss::Channel::Item
  • RSS::Rss::Channel::Item::Category
  • RSS::Rss::Channel::Item::Enclosure
  • RSS::Rss::Channel::Item::Guid
  • RSS::Rss::Channel::Item::Source
  • RSS::Rss::Channel::SkipDays
  • RSS::Rss::Channel::SkipDays::Day
  • RSS::Rss::Channel::SkipHours
  • RSS::Rss::Channel::SkipHours::Hour
  • RSS::Rss::Channel::TextInput
  • RSS::SetupMaker
  • RSS::SlashModel
  • RSS::SyndicationModel
  • RSS::TaxonomyTopicModel
  • RSS::TaxonomyTopicModel::TaxonomyTopic
  • RSS::TaxonomyTopicsModel
  • RSS::TaxonomyTopicsModel::TaxonomyTopics
  • RSS::TaxonomyTopicsModel::TaxonomyTopics::Bag
  • RSS::TooMuchTagError
  • RSS::TrackBackModel10
  • RSS::TrackBackModel10::TrackBackAbout
  • RSS::TrackBackModel10::TrackBackPing
  • RSS::TrackBackModel20
  • RSS::TrackBackModel20::TrackBackAbout
  • RSS::TrackBackModel20::TrackBackPing
  • RSS::TrackBackUtils
  • RSS::UnknownConversionMethodError
  • RSS::UnknownConvertMethod
  • RSS::UnknownTagError
  • RSS::UnsupportedMakerVersionError
  • RSS::Utils
  • RSS::Utils::CSV
  • RSS::Utils::InheritedReader
  • RSS::Utils::YesCleanOther
  • RSS::Utils::YesOther
  • RSS::XML
  • RSS::XML::Element
  • RSS::XMLParserListener
  • RSS::XMLParserNotFound
  • RSS::XMLParserParser
  • RSS::XMLScanListener
  • RSS::XMLScanParser
  • RSS::XMLStyleSheet
  • RSS::XMLStyleSheetMixin
  • Gem::AvailableSet
  • Gem::Command
  • Gem::CommandLineError
  • Gem::CommandManager
  • Gem::Commands
  • Gem::Commands::BuildCommand
  • Gem::Commands::CertCommand
  • Gem::Commands::CheckCommand
  • Gem::Commands::CleanupCommand
  • Gem::Commands::ContentsCommand
  • Gem::Commands::DependencyCommand
  • Gem::Commands::EnvironmentCommand
  • Gem::Commands::FetchCommand
  • Gem::Commands::GenerateIndexCommand
  • Gem::Commands::HelpCommand
  • Gem::Commands::InstallCommand
  • Gem::Commands::ListCommand
  • Gem::Commands::LockCommand
  • Gem::Commands::MirrorCommand
  • Gem::Commands::OutdatedCommand
  • Gem::Commands::OwnerCommand
  • Gem::Commands::PristineCommand
  • Gem::Commands::PushCommand
  • Gem::Commands::QueryCommand
  • Gem::Commands::RdocCommand
  • Gem::Commands::SearchCommand
  • Gem::Commands::ServerCommand
  • Gem::Commands::SetupCommand
  • Gem::Commands::SourcesCommand
  • Gem::Commands::SpecificationCommand
  • Gem::Commands::StaleCommand
  • Gem::Commands::UninstallCommand
  • Gem::Commands::UnpackCommand
  • Gem::Commands::UpdateCommand
  • Gem::Commands::WhichCommand
  • Gem::Commands::YankCommand
  • Gem::ConfigFile
  • Gem::ConsoleUI
  • Gem::DefaultUserInteraction
  • Gem::Dependency
  • Gem::DependencyError
  • Gem::DependencyInstaller
  • Gem::DependencyList
  • Gem::DependencyRemovalException
  • Gem::DependencyResolutionError
  • Gem::DependencyResolver
  • Gem::DependencyResolver::APISet
  • Gem::DependencyResolver::APISpecification
  • Gem::DependencyResolver::ActivationRequest
  • Gem::DependencyResolver::CurrentSet
  • Gem::DependencyResolver::DependencyConflict
  • Gem::DependencyResolver::DependencyRequest
  • Gem::DependencyResolver::IndexSet
  • Gem::DependencyResolver::IndexSpecification
  • Gem::Deprecate
  • Gem::Doctor
  • Gem::DocumentError
  • Gem::EndOfYAMLException
  • Gem::ErrorReason
  • Gem::Exception
  • Gem::Ext
  • Gem::Ext::Builder
  • Gem::Ext::CmakeBuilder
  • Gem::Ext::ConfigureBuilder
  • Gem::Ext::ExtConfBuilder
  • Gem::Ext::RakeBuilder
  • Gem::FakeFetcher
  • Gem::FilePermissionError
  • Gem::FormatException
  • Gem::GemNotFoundException
  • Gem::GemNotInHomeException
  • Gem::GemRunner
  • Gem::GemcutterUtilities
  • Gem::ImpossibleDependenciesError
  • Gem::Indexer
  • Gem::InstallError
  • Gem::InstallUpdateOptions
  • Gem::Installer
  • Gem::Installer::ExtensionBuildError
  • Gem::InstallerTestCase
  • Gem::InvalidSpecificationException
  • Gem::LoadError
  • Gem::LocalRemoteOptions
  • Gem::MockGemUi
  • Gem::MockGemUi::InputEOFError
  • Gem::MockGemUi::SystemExitException
  • Gem::MockGemUi::TTY
  • Gem::MockGemUi::TermError
  • Gem::NameTuple
  • Gem::NoAliasYAMLTree
  • Gem::OperationNotSupportedError
  • Gem::Package
  • Gem::Package::DigestIO
  • Gem::Package::Error
  • Gem::Package::FormatError
  • Gem::Package::NonSeekableIO
  • Gem::Package::Old
  • Gem::Package::PathError
  • Gem::Package::TarHeader
  • Gem::Package::TarInvalidError
  • Gem::Package::TarReader
  • Gem::Package::TarReader::Entry
  • Gem::Package::TarReader::UnexpectedEOF
  • Gem::Package::TarTestCase
  • Gem::Package::TarWriter
  • Gem::Package::TarWriter::BoundedStream
  • Gem::Package::TarWriter::FileOverflow
  • Gem::Package::TarWriter::RestrictedStream
  • Gem::Package::TooLongFileName
  • Gem::PackageTask
  • Gem::PathSupport
  • Gem::Platform
  • Gem::PlatformMismatch
  • Gem::RemoteError
  • Gem::RemoteFetcher
  • Gem::RemoteFetcher::FetchError
  • Gem::RemoteFetcher::UnknownHostError
  • Gem::RemoteInstallationCancelled
  • Gem::RemoteInstallationSkipped
  • Gem::RemoteSourceException
  • Gem::RequestSet
  • Gem::RequestSet::GemDepedencyAPI
  • Gem::Requirement
  • Gem::Requirement::BadRequirementError
  • Gem::Security
  • Gem::Security::DIGEST_ALGORITHM
  • Gem::Security::Exception
  • Gem::Security::KEY_ALGORITHM
  • Gem::Security::Policy
  • Gem::Security::Signer
  • Gem::Security::TrustDir
  • Gem::Server
  • Gem::SilentUI
  • Gem::Source
  • Gem::Source::Local
  • Gem::Source::SpecificFile
  • Gem::SourceFetchProblem
  • Gem::SourceList
  • Gem::SpecFetcher
  • Gem::SpecificGemNotFoundException
  • Gem::Specification
  • Gem::StreamUI
  • Gem::StreamUI::SilentDownloadReporter
  • Gem::StreamUI::SilentProgressReporter
  • Gem::StreamUI::SimpleProgressReporter
  • Gem::StreamUI::VerboseDownloadReporter
  • Gem::StreamUI::VerboseProgressReporter
  • Gem::SystemExitException
  • Gem::TestCase
  • Gem::TestCase::StaticSet
  • Gem::Text
  • Gem::Uninstaller
  • Gem::UnsatisfiableDepedencyError
  • Gem::UserInteraction
  • Gem::Validator
  • Gem::VerificationError
  • Gem::Version
  • Gem::Version::Requirement
  • Gem::VersionOption
  • Net
  • Net::APOP
  • Net::APOPSession
  • Net::FTP
  • Net::HTTP
  • Net::HTTP
  • Net::HTTP::Copy
  • Net::HTTP::Delete
  • Net::HTTP::Get
  • Net::HTTP::Head
  • Net::HTTP::Lock
  • Net::HTTP::Mkcol
  • Net::HTTP::Move
  • Net::HTTP::Options
  • Net::HTTP::Patch
  • Net::HTTP::Post
  • Net::HTTP::Propfind
  • Net::HTTP::Proppatch
  • Net::HTTP::Put
  • Net::HTTP::Trace
  • Net::HTTP::Unlock
  • Net::HTTPAccepted
  • Net::HTTPBadGateway
  • Net::HTTPBadRequest
  • Net::HTTPClientError
  • Net::HTTPConflict
  • Net::HTTPContinue
  • Net::HTTPCreated
  • Net::HTTPError
  • Net::HTTPExceptions
  • Net::HTTPExpectationFailed
  • Net::HTTPFailedDependency
  • Net::HTTPFatalError
  • Net::HTTPForbidden
  • Net::HTTPFound
  • Net::HTTPFound
  • Net::HTTPGatewayTimeOut
  • Net::HTTPGenericRequest
  • Net::HTTPGone
  • Net::HTTPHeader
  • Net::HTTPInformation
  • Net::HTTPInformation::EXCEPTION_TYPE
  • Net::HTTPInsufficientStorage
  • Net::HTTPInternalServerError
  • Net::HTTPLengthRequired
  • Net::HTTPLocked
  • Net::HTTPMethodNotAllowed
  • Net::HTTPMovedPermanently
  • Net::HTTPMultiStatus
  • Net::HTTPMultipleChoices
  • Net::HTTPMultipleChoices
  • Net::HTTPNetworkAuthenticationRequired
  • Net::HTTPNoContent
  • Net::HTTPNonAuthoritativeInformation
  • Net::HTTPNotAcceptable
  • Net::HTTPNotFound
  • Net::HTTPNotImplemented
  • Net::HTTPNotModified
  • Net::HTTPOK
  • Net::HTTPPartialContent
  • Net::HTTPPaymentRequired
  • Net::HTTPPreconditionFailed
  • Net::HTTPPreconditionRequired
  • Net::HTTPProxyAuthenticationRequired
  • Net::HTTPRedirection
  • Net::HTTPRedirection::EXCEPTION_TYPE
  • Net::HTTPRequest
  • Net::HTTPRequestEntityTooLarge
  • Net::HTTPRequestHeaderFieldsTooLarge
  • Net::HTTPRequestTimeOut
  • Net::HTTPRequestURITooLong
  • Net::HTTPRequestURITooLong
  • Net::HTTPRequestedRangeNotSatisfiable
  • Net::HTTPResetContent
  • Net::HTTPResponse
  • Net::HTTPRetriableError
  • Net::HTTPSeeOther
  • Net::HTTPServerError
  • Net::HTTPServerException
  • Net::HTTPServiceUnavailable
  • Net::HTTPSuccess
  • Net::HTTPSuccess::EXCEPTION_TYPE
  • Net::HTTPSwitchProtocol
  • Net::HTTPTemporaryRedirect
  • Net::HTTPTooManyRequests
  • Net::HTTPUnauthorized
  • Net::HTTPUnknownResponse
  • Net::HTTPUnknownResponse::EXCEPTION_TYPE
  • Net::HTTPUnprocessableEntity
  • Net::HTTPUnsupportedMediaType
  • Net::HTTPUpgradeRequired
  • Net::HTTPUseProxy
  • Net::HTTPVersionNotSupported
  • Net::IMAP
  • Net::IMAP::BadResponseError
  • Net::IMAP::BodyTypeAttachment
  • Net::IMAP::BodyTypeBasic
  • Net::IMAP::BodyTypeExtension
  • Net::IMAP::BodyTypeMessage
  • Net::IMAP::BodyTypeMultipart
  • Net::IMAP::BodyTypeText
  • Net::IMAP::ByeResponseError
  • Net::IMAP::CramMD5Authenticator
  • Net::IMAP::DataFormatError
  • Net::IMAP::DigestMD5Authenticator
  • Net::IMAP::Error
  • Net::IMAP::FlagCountError
  • Net::IMAP::LoginAuthenticator
  • Net::IMAP::NoResponseError
  • Net::IMAP::PlainAuthenticator
  • Net::IMAP::ResponseError
  • Net::IMAP::ResponseParseError
  • Net::OpenTimeout
  • Net::POP3
  • Net::POPAuthenticationError
  • Net::POPBadResponse
  • Net::POPError
  • Net::POPMail
  • Net::ProtoAuthError
  • Net::ProtoCommandError
  • Net::ProtoFatalError
  • Net::ProtoRetriableError
  • Net::ProtoRetriableError
  • Net::ProtoServerError
  • Net::ProtoSyntaxError
  • Net::ProtoUnknownError
  • Net::ProtocolError
  • Net::ReadTimeout
  • Net::SMTP
  • Net::SMTP::Response
  • Net::SMTPAuthenticationError
  • Net::SMTPError
  • Net::SMTPFatalError
  • Net::SMTPServerBusy
  • Net::SMTPSyntaxError
  • Net::SMTPUnknownError
  • Net::SMTPUnsupportedCommand
  • Net::Telnet
  • Net::WriteAdapter
  • OpenSSL
  • OpenSSL::ASN1
  • OpenSSL::ASN1::ASN1Data
  • OpenSSL::ASN1::ASN1Error
  • OpenSSL::ASN1::Constructive
  • OpenSSL::ASN1::ObjectId
  • OpenSSL::ASN1::Primitive
  • OpenSSL::BN
  • OpenSSL::BNError
  • OpenSSL::Buffering
  • OpenSSL::Cipher
  • OpenSSL::Cipher::Cipher
  • OpenSSL::Cipher::CipherError
  • OpenSSL::Config
  • OpenSSL::ConfigError
  • OpenSSL::Digest
  • OpenSSL::Digest::Digest
  • OpenSSL::Digest::DigestError
  • OpenSSL::Engine
  • OpenSSL::Engine::EngineError
  • OpenSSL::HMAC
  • OpenSSL::HMACError
  • OpenSSL::Netscape
  • OpenSSL::Netscape::SPKI
  • OpenSSL::Netscape::SPKIError
  • OpenSSL::OCSP
  • OpenSSL::OCSP::BasicResponse
  • OpenSSL::OCSP::CertificateId
  • OpenSSL::OCSP::OCSPError
  • OpenSSL::OCSP::Request
  • OpenSSL::OCSP::Response
  • OpenSSL::OpenSSLError
  • OpenSSL::PKCS12
  • OpenSSL::PKCS12::PKCS12Error
  • OpenSSL::PKCS5
  • OpenSSL::PKCS5::PKCS5Error
  • OpenSSL::PKCS7
  • OpenSSL::PKCS7::PKCS7Error
  • OpenSSL::PKCS7::RecipientInfo
  • OpenSSL::PKCS7::SignerInfo
  • OpenSSL::PKey
  • OpenSSL::PKey::DH
  • OpenSSL::PKey::DHError
  • OpenSSL::PKey::DSA
  • OpenSSL::PKey::DSAError
  • OpenSSL::PKey::EC
  • OpenSSL::PKey::EC::Group
  • OpenSSL::PKey::EC::Group::Error
  • OpenSSL::PKey::EC::Point
  • OpenSSL::PKey::EC::Point::Error
  • OpenSSL::PKey::ECError
  • OpenSSL::PKey::PKey
  • OpenSSL::PKey::PKeyError
  • OpenSSL::PKey::RSA
  • OpenSSL::PKey::RSAError
  • OpenSSL::Random
  • OpenSSL::Random::RandomError
  • OpenSSL::SSL
  • OpenSSL::SSL::Nonblock
  • OpenSSL::SSL::SSLContext
  • OpenSSL::SSL::SSLError
  • OpenSSL::SSL::SSLServer
  • OpenSSL::SSL::SSLSocket
  • OpenSSL::SSL::Session
  • OpenSSL::SSL::Session::SessionError
  • OpenSSL::SSL::SocketForwarder
  • OpenSSL::X509
  • OpenSSL::X509::Attribute
  • OpenSSL::X509::AttributeError
  • OpenSSL::X509::CRL
  • OpenSSL::X509::CRLError
  • OpenSSL::X509::Certificate
  • OpenSSL::X509::CertificateError
  • OpenSSL::X509::Extension
  • OpenSSL::X509::ExtensionError
  • OpenSSL::X509::ExtensionFactory
  • OpenSSL::X509::Name
  • OpenSSL::X509::Name::RFC2253DN
  • OpenSSL::X509::NameError
  • OpenSSL::X509::Request
  • OpenSSL::X509::RequestError
  • OpenSSL::X509::Revoked
  • OpenSSL::X509::RevokedError
  • OpenSSL::X509::Store
  • OpenSSL::X509::StoreContext
  • OpenSSL::X509::StoreError
  • REXML
  • REXML::AttlistDecl
  • REXML::Attribute
  • REXML::Attributes
  • REXML::CData
  • REXML::Child
  • REXML::Comment
  • REXML::DTD
  • REXML::DTD::AttlistDecl
  • REXML::DTD::ElementDecl
  • REXML::DTD::EntityDecl
  • REXML::DTD::NotationDecl
  • REXML::DTD::Parser
  • REXML::Declaration
  • REXML::DocType
  • REXML::Document
  • REXML::Element
  • REXML::ElementDecl
  • REXML::Elements
  • REXML::Encoding
  • REXML::Entity
  • REXML::EntityConst
  • REXML::ExternalEntity
  • REXML::Formatters
  • REXML::Formatters::Default
  • REXML::Formatters::Pretty
  • REXML::Formatters::Transitive
  • REXML::Functions
  • REXML::IOSource
  • REXML::Instruction
  • REXML::Light
  • REXML::Light::Node
  • REXML::Namespace
  • REXML::Node
  • REXML::NotationDecl
  • REXML::Output
  • REXML::Parent
  • REXML::ParseException
  • REXML::Parsers
  • REXML::Parsers::BaseParser
  • REXML::Parsers::LightParser
  • REXML::Parsers::PullEvent
  • REXML::Parsers::PullParser
  • REXML::Parsers::SAX2Parser
  • REXML::Parsers::StreamParser
  • REXML::Parsers::TreeParser
  • REXML::Parsers::UltraLightParser
  • REXML::Parsers::XPathParser
  • REXML::QuickPath
  • REXML::SAX2Listener
  • REXML::Source
  • REXML::SourceFactory
  • REXML::StreamListener
  • REXML::SyncEnumerator
  • REXML::Text
  • REXML::UndefinedNamespaceException
  • REXML::Validation
  • REXML::Validation::Choice
  • REXML::Validation::Event
  • REXML::Validation::Interleave
  • REXML::Validation::OneOrMore
  • REXML::Validation::Optional
  • REXML::Validation::Ref
  • REXML::Validation::RelaxNG
  • REXML::Validation::Sequence
  • REXML::Validation::State
  • REXML::Validation::ValidationException
  • REXML::Validation::Validator
  • REXML::Validation::ZeroOrMore
  • REXML::XMLDecl
  • REXML::XMLTokens
  • REXML::XPath
  • REXML::XPathParser
  • WEBrick
  • WEBrick::AccessLog
  • WEBrick::AccessLog::AccessLogError
  • WEBrick::BasicLog
  • WEBrick::CGI
  • WEBrick::Config
  • WEBrick::Cookie
  • WEBrick::Daemon
  • WEBrick::GenericServer
  • WEBrick::HTMLUtils
  • WEBrick::HTTPAuth
  • WEBrick::HTTPAuth::Authenticator
  • WEBrick::HTTPAuth::BasicAuth
  • WEBrick::HTTPAuth::DigestAuth
  • WEBrick::HTTPAuth::Htdigest
  • WEBrick::HTTPAuth::Htgroup
  • WEBrick::HTTPAuth::Htpasswd
  • WEBrick::HTTPAuth::ProxyAuthenticator
  • WEBrick::HTTPAuth::ProxyBasicAuth
  • WEBrick::HTTPAuth::ProxyDigestAuth
  • WEBrick::HTTPAuth::UserDB
  • WEBrick::HTTPProxyServer
  • WEBrick::HTTPRequest
  • WEBrick::HTTPResponse
  • WEBrick::HTTPServer
  • WEBrick::HTTPServerError
  • WEBrick::HTTPServlet
  • WEBrick::HTTPServlet::AbstractServlet
  • WEBrick::HTTPServlet::CGIHandler
  • WEBrick::HTTPServlet::DefaultFileHandler
  • WEBrick::HTTPServlet::ERBHandler
  • WEBrick::HTTPServlet::FileHandler
  • WEBrick::HTTPServlet::HTTPServletError
  • WEBrick::HTTPServlet::ProcHandler
  • WEBrick::HTTPStatus
  • WEBrick::HTTPStatus::ClientError
  • WEBrick::HTTPStatus::EOFError
  • WEBrick::HTTPStatus::Error
  • WEBrick::HTTPStatus::Info
  • WEBrick::HTTPStatus::Redirect
  • WEBrick::HTTPStatus::ServerError
  • WEBrick::HTTPStatus::Status
  • WEBrick::HTTPStatus::Success
  • WEBrick::HTTPUtils
  • WEBrick::HTTPUtils::FormData
  • WEBrick::HTTPVersion
  • WEBrick::Log
  • WEBrick::ServerError
  • WEBrick::SimpleServer
  • WEBrick::Utils
  • WEBrick::Utils::TimeoutHandler
  • IRB::Abort
  • IRB::Context
  • IRB::ContextExtender
  • IRB::ExtendCommandBundle
  • IRB::FileInputMethod
  • IRB::Frame
  • IRB::InputMethod
  • IRB::Inspector
  • IRB::Irb
  • IRB::IrbLoader
  • IRB::JobManager
  • IRB::LoadAbort
  • IRB::MethodExtender
  • IRB::Notifier
  • IRB::Notifier::AbstractNotifier
  • IRB::Notifier::CompositeNotifier
  • IRB::Notifier::LeveledNotifier
  • IRB::Notifier::NoMsgNotifier
  • IRB::OutputMethod
  • IRB::ReadlineInputMethod
  • IRB::StdioInputMethod
  • IRB::StdioOutputMethod
  • IRB::WorkSpace
  • Rake::AltSystem
  • Rake::Application
  • Rake::Application
  • Rake::Backtrace
  • Rake::Cloneable
  • Rake::CompositePublisher
  • Rake::DSL
  • Rake::DefaultLoader
  • Rake::EarlyTime
  • Rake::FileCreationTask
  • Rake::FileList
  • Rake::FileList
  • Rake::FileTask
  • Rake::FileUtilsExt
  • Rake::FileUtilsExt
  • Rake::FtpFile
  • Rake::FtpUploader
  • Rake::InvocationChain
  • Rake::InvocationChain::EmptyInvocationChain
  • Rake::InvocationExceptionMixin
  • Rake::MakefileLoader
  • Rake::MultiTask
  • Rake::NameSpace
  • Rake::PackageTask
  • Rake::PrivateReader
  • Rake::PseudoStatus
  • Rake::RubyForgePublisher
  • Rake::RuleRecursionOverflowError
  • Rake::SshDirPublisher
  • Rake::SshFilePublisher
  • Rake::SshFreshDirPublisher
  • Rake::Task
  • Rake::TaskArgumentError
  • Rake::TaskArguments
  • Rake::TaskLib
  • Rake::TaskManager
  • Rake::TestTask
  • Rake::TraceOutput
  • Rake::Win32
  • Rake::Win32::Win32HomeError
  • XMLRPC
  • XMLRPC::Base64
  • XMLRPC::BasicServer
  • XMLRPC::CGIServer
  • XMLRPC::Client
  • XMLRPC::Client::Proxy
  • XMLRPC::Config
  • XMLRPC::Convert
  • XMLRPC::Create
  • XMLRPC::DateTime
  • XMLRPC::FaultException
  • XMLRPC::Marshal
  • XMLRPC::Marshallable
  • XMLRPC::ModRubyServer
  • XMLRPC::ParseContentType
  • XMLRPC::ParserWriterChooseMixin
  • XMLRPC::Server
  • XMLRPC::Service
  • XMLRPC::Service::BasicInterface
  • XMLRPC::Service::Interface
  • XMLRPC::Service::PublicInstanceMethodsInterface
  • XMLRPC::WEBrickServlet
  • XMLRPC::XMLParser
  • XMLRPC::XMLParser::AbstractStreamParser
  • XMLRPC::XMLParser::AbstractTreeParser
  • XMLRPC::XMLParser::NQXMLParser
  • XMLRPC::XMLParser::NQXMLStreamParser
  • XMLRPC::XMLParser::NQXMLStreamParser::XMLRPCParser
  • XMLRPC::XMLParser::NQXMLTreeParser
  • XMLRPC::XMLParser::REXMLStreamParser
  • XMLRPC::XMLParser::REXMLStreamParser::StreamListener
  • XMLRPC::XMLParser::StreamParserMixin
  • XMLRPC::XMLParser::XMLParser
  • XMLRPC::XMLParser::XMLScanStreamParser
  • XMLRPC::XMLParser::XMLScanStreamParser::XMLScanParser
  • XMLRPC::XMLParser::XMLStreamParser
  • XMLRPC::XMLParser::XMLTreeParser
  • XMLRPC::XMLWriter
  • XMLRPC::XMLWriter::Abstract
  • XMLRPC::XMLWriter::Simple
  • XMLRPC::XMLWriter::XMLParser
  • Psych
  • Psych::BadAlias
  • Psych::Coder
  • Psych::Error
  • Psych::Exception
  • Psych::Handler
  • Psych::Handler::DumperOptions
  • Psych::Handlers
  • Psych::Handlers::Recorder
  • Psych::JSON
  • Psych::JSON::Stream
  • Psych::JSON::TreeBuilder
  • Psych::Nodes
  • Psych::Nodes::Alias
  • Psych::Nodes::Document
  • Psych::Nodes::Mapping
  • Psych::Nodes::Node
  • Psych::Nodes::Scalar
  • Psych::Nodes::Sequence
  • Psych::Nodes::Stream
  • Psych::Omap
  • Psych::Parser
  • Psych::Parser::Mark
  • Psych::PrivateType
  • Psych::ScalarScanner
  • Psych::Set
  • Psych::Stream
  • Psych::Streaming
  • Psych::SyntaxError
  • Psych::TreeBuilder
  • Psych::Visitors
  • Psych::Visitors::DepthFirst
  • Psych::Visitors::Emitter
  • Psych::Visitors::JSONTree
  • Psych::Visitors::ToRuby
  • Psych::Visitors::Visitor
  • Psych::Visitors::YAMLTree
  • Resolv
  • Resolv::DNS
  • Resolv::DNS::Config
  • Resolv::DNS::Config::NXDomain
  • Resolv::DNS::Config::OtherResolvError
  • Resolv::DNS::DecodeError
  • Resolv::DNS::EncodeError
  • Resolv::DNS::Name
  • Resolv::DNS::Query
  • Resolv::DNS::Requester
  • Resolv::DNS::Requester::RequestError
  • Resolv::DNS::Resource
  • Resolv::DNS::Resource::ANY
  • Resolv::DNS::Resource::CNAME
  • Resolv::DNS::Resource::DomainName
  • Resolv::DNS::Resource::Generic
  • Resolv::DNS::Resource::HINFO
  • Resolv::DNS::Resource::IN
  • Resolv::DNS::Resource::IN::A
  • Resolv::DNS::Resource::IN::AAAA
  • Resolv::DNS::Resource::IN::SRV
  • Resolv::DNS::Resource::IN::WKS
  • Resolv::DNS::Resource::MINFO
  • Resolv::DNS::Resource::MX
  • Resolv::DNS::Resource::NS
  • Resolv::DNS::Resource::PTR
  • Resolv::DNS::Resource::SOA
  • Resolv::DNS::Resource::TXT
  • Resolv::Hosts
  • Resolv::IPv4
  • Resolv::IPv6
  • Resolv::ResolvError
  • Resolv::ResolvTimeout
  • DRb
  • DRb::DRbArray
  • DRb::DRbBadScheme
  • DRb::DRbBadURI
  • DRb::DRbConn
  • DRb::DRbConnError
  • DRb::DRbError
  • DRb::DRbIdConv
  • DRb::DRbIdConv
  • DRb::DRbMessage
  • DRb::DRbObject
  • DRb::DRbObject
  • DRb::DRbObservable
  • DRb::DRbProtocol
  • DRb::DRbRemoteError
  • DRb::DRbSSLSocket
  • DRb::DRbSSLSocket::SSLConfig
  • DRb::DRbServer
  • DRb::DRbServerNotFound
  • DRb::DRbTCPSocket
  • DRb::DRbUNIXSocket
  • DRb::DRbUndumped
  • DRb::DRbUndumped
  • DRb::DRbUnknown
  • DRb::DRbUnknownError
  • DRb::ExtServ
  • DRb::ExtServManager
  • DRb::GW
  • DRb::GWIdConv
  • DRb::TimerIdConv
  • DRb::TimerIdConv::TimerHolder2
  • DRb::TimerIdConv::TimerHolder2::InvalidIndexError
  • DL
  • DL::BasicTypes
  • DL::CFunc
  • DL::CParser
  • DL::CPtr
  • DL::CStruct
  • DL::CStructBuilder
  • DL::CStructEntity
  • DL::CUnion
  • DL::CUnionEntity
  • DL::CarriedFunction
  • DL::CompositeHandler
  • DL::DLError
  • DL::DLTypeError
  • DL::Function
  • DL::Handle
  • DL::Importer
  • DL::PackInfo
  • DL::Packer
  • DL::Stack
  • DL::TempFunction
  • DL::ValueUtil
  • DL::Win32Types
  • OptionParser
  • OptionParser::AC
  • OptionParser::Acceptables
  • OptionParser::AmbiguousArgument
  • OptionParser::AmbiguousOption
  • OptionParser::Arguable
  • OptionParser::CompletingHash
  • OptionParser::Completion
  • OptionParser::InvalidArgument
  • OptionParser::InvalidOption
  • OptionParser::List
  • OptionParser::MissingArgument
  • OptionParser::NeedlessArgument
  • OptionParser::OptionMap
  • OptionParser::ParseError
  • OptionParser::Switch
  • OptionParser::Switch::NoArgument
  • OptionParser::Switch::OptionalArgument
  • OptionParser::Switch::PlacedArgument
  • OptionParser::Switch::RequiredArgument
  • Rinda
  • Rinda::DRbObjectTemplate
  • Rinda::InvalidHashTupleKey
  • Rinda::NotifyTemplateEntry
  • Rinda::RequestCanceledError
  • Rinda::RequestExpiredError
  • Rinda::RindaError
  • Rinda::RingFinger
  • Rinda::RingProvider
  • Rinda::RingServer
  • Rinda::SimpleRenewer
  • Rinda::Template
  • Rinda::TemplateEntry
  • Rinda::Tuple
  • Rinda::TupleBag
  • Rinda::TupleBag::TupleBin
  • Rinda::TupleEntry
  • Rinda::TupleSpace
  • Rinda::TupleSpaceProxy
  • Rinda::WaitTemplateEntry
  • Zlib
  • Zlib::BufError
  • Zlib::DataError
  • Zlib::Deflate
  • Zlib::Error
  • Zlib::GzipFile
  • Zlib::GzipFile::CRCError
  • Zlib::GzipFile::Error
  • Zlib::GzipFile::LengthError
  • Zlib::GzipFile::NoFooter
  • Zlib::GzipReader
  • Zlib::GzipWriter
  • Zlib::Inflate
  • Zlib::MemError
  • Zlib::NeedDict
  • Zlib::StreamEnd
  • Zlib::StreamError
  • Zlib::VersionError
  • Zlib::ZStream
  • Fiddle
  • Fiddle::BasicTypes
  • Fiddle::CParser
  • Fiddle::CStruct
  • Fiddle::CStructBuilder
  • Fiddle::CStructEntity
  • Fiddle::CUnion
  • Fiddle::CUnionEntity
  • Fiddle::Closure
  • Fiddle::Closure::BlockCaller
  • Fiddle::CompositeHandler
  • Fiddle::DLError
  • Fiddle::Function
  • Fiddle::Handle
  • Fiddle::Importer
  • Fiddle::Pointer
  • Fiddle::Win32Types
  • Test
  • Test::Unit
  • Test::Unit::Assertions
  • Test::Unit::AutoRunner
  • Test::Unit::AutoRunner::Runner
  • Test::Unit::GCStressOption
  • Test::Unit::GlobOption
  • Test::Unit::LoadPathOption
  • Test::Unit::Options
  • Test::Unit::ProxyError
  • Test::Unit::RequireFiles
  • Test::Unit::RunCount
  • Test::Unit::Runner
  • Test::Unit::Runner::Worker
  • Test::Unit::StatusLineOutput
  • Test::Unit::TestCase
  • Test::Unit::Worker
  • Win32
  • Win32::Registry
  • Win32::Registry::API
  • Win32::Registry::Constants
  • Win32::Registry::Error
  • Win32::Registry::Error::Kernel32
  • Win32::Registry::PredefinedKey
  • Win32::Resolv
  • Win32::Resolv::Kernel32
  • Win32::SSPI
  • Win32::SSPI::API
  • Win32::SSPI::Identity
  • Win32::SSPI::NegotiateAuth
  • Win32::SSPI::SSPIResult
  • Win32::SSPI::SecurityBuffer
  • Win32::SSPI::SecurityHandle
  • Win32::SSPI::TimeStamp
  • URI
  • URI::BadURIError
  • URI::Error
  • URI::Escape
  • URI::FTP
  • URI::Generic
  • URI::HTTP
  • URI::HTTPS
  • URI::InvalidComponentError
  • URI::InvalidURIError
  • URI::LDAP
  • URI::LDAPS
  • URI::MailTo
  • URI::Parser
  • URI::REGEXP
  • URI::REGEXP::PATTERN
  • MiniTest
  • MiniTest::Assertion
  • MiniTest::Assertions
  • MiniTest::Expectations
  • MiniTest::Mock
  • MiniTest::Skip
  • MiniTest::Spec
  • MiniTest::Unit
  • MiniTest::Unit::Deprecated
  • MiniTest::Unit::Deprecated::Hooks
  • MiniTest::Unit::Deprecated::HooksCM
  • MiniTest::Unit::Guard
  • MiniTest::Unit::LifecycleHooks
  • MiniTest::Unit::TestCase
  • Shell
  • Shell::AppendFile
  • Shell::AppendIO
  • Shell::BuiltInCommand
  • Shell::Cat
  • Shell::CommandProcessor
  • Shell::Concat
  • Shell::Echo
  • Shell::Error
  • Shell::Filter
  • Shell::Glob
  • Shell::ProcessController
  • Shell::SystemCommand
  • Shell::Tee
  • Shell::Void
  • CGI
  • CGI::Cookie
  • CGI::HtmlExtension
  • CGI::InvalidEncoding
  • CGI::QueryExtension
  • CGI::Session
  • CGI::Session::FileStore
  • CGI::Session::MemoryStore
  • CGI::Session::NullStore
  • CGI::Session::PStore
  • JSON
  • JSON::Ext
  • JSON::GeneratorError
  • JSON::GenericObject
  • JSON::JSONError
  • JSON::MissingUnicodeSupport
  • JSON::NestingError
  • JSON::ParserError
  • JSON::UnparserError
  • Digest
  • Digest::Base
  • Digest::Class
  • Digest::HMAC
  • Digest::Instance
  • Digest::MD5
  • Digest::RMD160
  • Digest::SHA1
  • Prime
  • Prime::EratosthenesGenerator
  • Prime::EratosthenesSieve
  • Prime::Generator23
  • Prime::OldCompatibility
  • Prime::PseudoPrimeGenerator
  • Prime::TrialDivision
  • Prime::TrialDivisionGenerator
  • Syslog
  • Syslog::Constants
  • Syslog::Facility
  • Syslog::Level
  • Syslog::Logger
  • Syslog::Logger::Formatter
  • Syslog::Macros
  • Syslog::Option
  • YAML::DBM
  • YAML::Store
  • FileUtils
  • FileUtils::DryRun
  • FileUtils::LowMethods
  • FileUtils::NoWrite
  • FileUtils::StreamUtils_
  • FileUtils::Verbose
  • GetoptLong
  • GetoptLong::AmbiguousOption
  • GetoptLong::Error
  • GetoptLong::InvalidOption
  • GetoptLong::MissingArgument
  • GetoptLong::NeedlessArgument
  • Logger
  • Logger::Application
  • Logger::Formatter
  • Logger::LogDevice
  • Logger::LogDevice::LogDeviceMutex
  • Logger::Severity
  • Object
  • Object::ParseError
  • Object::Synchronizer
  • Object::Synchronizer_m
  • Object::ThWait
  • Object::TimeoutError
  • PrettyPrint
  • PrettyPrint::Breakable
  • PrettyPrint::Group
  • PrettyPrint::GroupQueue
  • PrettyPrint::SingleLine
  • PrettyPrint::Text
  • Curses
  • Curses::Key
  • Curses::MouseEvent
  • Curses::Pad
  • Curses::Window
  • IPAddr
  • IPAddr::AddressFamilyError
  • IPAddr::Error
  • IPAddr::InvalidAddressError
  • IPAddr::InvalidPrefixError
  • OpenURI
  • OpenURI::HTTPError
  • OpenURI::HTTPRedirect
  • OpenURI::Meta
  • OpenURI::OpenRead
  • Racc
  • Racc::CparseParams
  • Racc::ParseError
  • Racc::ParseError
  • Racc::Parser
  • Sync_m
  • Sync_m
  • Sync_m::Err
  • Sync_m::Err::LockModeFailer
  • Sync_m::Err::UnknownLocker
  • CSV
  • CSV::MalformedCSVError
  • CSV::Row
  • CSV::Table
  • Errno
  • Errno::ECONNABORTED
  • Errno::ECONNRESET
  • Errno::EPROTO
  • HttpServer
  • HttpServer::Request
  • HttpServer::Response
  • HttpServer::Table
  • PP
  • PP::ObjectMixin
  • PP::PPMethods
  • PP::SingleLine
  • Socket
  • Socket::AncillaryData
  • Socket::Option
  • Socket::UDPSource
  • ACL
  • ACL::ACLEntry
  • ACL::ACLList
  • ERB
  • ERB::DefMethod
  • ERB::Util
  • IO
  • IO::readable
  • IO::writable
  • MakeMakefile
  • Matrix
  • Matrix::EigenvalueDecomposition
  • Matrix::LUPDecomposition
  • MonitorMixin
  • MonitorMixin::ConditionVariable
  • MonitorMixin::ConditionVariable::Timeout
  • Scanf
  • Timeout
  • Timeout::Error
  • Timeout::Error
  • Benchmark
  • Benchmark::Tms
  • Exception2MessageMapper
  • Exception2MessageMapper::E2MM
  • File
  • File::Stat
  • Minitest
  • Minitest::Unit
  • NQXML
  • NQXML::Node
  • PStore
  • PStore::Error
  • PTY
  • PTY::ChildExited
  • Ripper
  • Ripper::Filter
  • StringScanner
  • StringScanner::Error
  • Sync
  • Sync
  • TSort
  • TSort::Cyclic
  • Tempfile
  • ThreadsWait
  • ThreadsWait
  • Vector
  • Vector::ZeroVectorError
  • WIN32OLE
  • WIN32OLE::VARIANT
  • WeakRef
  • WeakRef::RefError
  • XML
  • XML::Parser
  • XMLEncoding_ja
  • XMLEncoding_ja::SJISHandler
  • XMP
  • XMP::StringInputMethod
  • Abbrev
  • Addrinfo
  • Base64
  • BasicSocket
  • BigDecimal
  • BigMath
  • CMath
  • Class
  • Complex
  • CompositePublisher
  • ConditionVariable
  • Coverage
  • DBM
  • DBMError
  • DEBUGGER__
  • DateTime
  • Delegator
  • Dir
  • ENV
  • English
  • Enumerable
  • Etc
  • Exception
  • Fcntl
  • Find
  • Float
  • Forwardable
  • GDBM
  • GDBMError
  • GDBMFatalError
  • GServer
  • Hash
  • IPSocket
  • Integer
  • Jacobian
  • Kconv
  • Kernel
  • LUSolve
  • MatchData
  • Math
  • Module
  • Monitor
  • Mutex_m
  • NKF
  • Newton
  • Numeric
  • OLEProperty
  • Observable
  • Open3
  • OpenStruct
  • ParallelEach
  • Pathname
  • PrideIO
  • PrideLOL
  • Profiler__
  • Queue
  • Range
  • Rational
  • Readline
  • Regexp
  • SDBM
  • SDBMError
  • SOCKSSocket
  • SecureRandom
  • Set
  • Shellwords
  • SimpleDelegator
  • SingleForwardable
  • Singleton
  • SizedQueue
  • SocketError
  • SortedSet
  • SshDirPublisher
  • SshFilePublisher
  • SshFreshDirPublisher
  • StringIO
  • Struct
  • Symbol
  • Sys
  • TCPServer
  • TCPSocket
  • TempIO
  • ThreadError
  • Time
  • Tracer
  • UDPSocket
  • UNIXServer
  • UNIXSocket
  • WIN32OLERuntimeError
  • WIN32OLE_EVENT
  • WIN32OLE_METHOD
  • WIN32OLE_PARAM
  • WIN32OLE_TYPE
  • WIN32OLE_TYPELIB
  • WIN32OLE_VARIABLE
  • WIN32OLE_VARIANT
  • Win32API

Generated by RDoc 3.12.2.

Generated with the Darkfish Rdoc Generator 3.


class ACL - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class ACL

Simple Access Control Lists.

Access control lists are composed of “allow” and “deny” halves to control access. Use “all” or “*” to match any address. To match a specific address use any address or address mask that IPAddr can understand.

Example:

list = %w[
  deny all
  allow 192.168.1.1
  allow ::ffff:192.168.1.2
  allow 192.168.1.3
]

# From Socket#peeraddr, see also ACL#allow_socket?
addr = ["AF_INET", 10, "lc630", "192.168.1.3"]

acl = ACL.new
p acl.allow_addr?(addr) # => true

acl = ACL.new(list, ACL::DENY_ALLOW)
p acl.allow_addr?(addr) # => true

In Files

  • lib/drb/acl.rb

Parent

Object

Constants

ALLOW_DENY

Default to allow

DENY_ALLOW

Default to deny

VERSION

The current version of ACL

Public Class Methods

new(list=nil, order = DENY_ALLOW) click to toggle source

Creates a new ACL from list with an evaluation order of DENY_ALLOW or ALLOW_DENY.

An ACL list is an Array of “allow” or “deny” and an address or address mask or “all” or “*” to match any address:

%w[
  deny all
  allow 192.0.2.2
  allow 192.0.2.128/26
]
# File lib/drb/acl.rb, line 172
def initialize(list=nil, order = DENY_ALLOW)
  @order = order
  @deny = ACLList.new
  @allow = ACLList.new
  install_list(list) if list
end

Public Instance Methods

allow_addr?(addr) click to toggle source

Allow connections from addrinfo addr? It must be formatted like Socket#peeraddr:

["AF_INET", 10, "lc630", "192.0.2.1"]
# File lib/drb/acl.rb, line 196
def allow_addr?(addr)
  case @order
  when DENY_ALLOW
    return true if @allow.match(addr)
    return false if @deny.match(addr)
    return true
  when ALLOW_DENY
    return false if @deny.match(addr)
    return true if @allow.match(addr)
    return false
  else
    false
  end
end
allow_socket?(soc) click to toggle source

Allow connections from Socket soc?

# File lib/drb/acl.rb, line 184
def allow_socket?(soc)
  allow_addr?(soc.peeraddr)
end
install_list(list) click to toggle source

Adds list of ACL entries to this ACL.

# File lib/drb/acl.rb, line 216
def install_list(list)
  i = 0
  while i < list.size
    permission, domain = list.slice(i,2)
    case permission.downcase
    when 'allow'
      @allow.add(domain)
    when 'deny'
      @deny.add(domain)
    else
      raise "Invalid ACL entry #{list.to_s}"
    end
    i += 2
  end
end


class ACL::ACLEntry - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class ACL::ACLEntry

An entry in an ACL

In Files

  • lib/drb/acl.rb

Parent

Object

Public Class Methods

new(str) click to toggle source

Creates a new entry using str.

str may be “*” or “all” to match any address, an IP address string to match a specific address, an IP address mask per IPAddr, or one containing “*” to match part of an IPv4 address.

# File lib/drb/acl.rb, line 52
def initialize(str)
  if str == '*' or str == 'all'
    @pat = [:all]
  elsif str.include?('*')
    @pat = [:name, dot_pat(str)]
  else
    begin
      @pat = [:ip, IPAddr.new(str)]
    rescue ArgumentError
      @pat = [:name, dot_pat(str)]
    end
  end
end

Public Instance Methods

match(addr) click to toggle source

Matches addr against this entry.

# File lib/drb/acl.rb, line 93
def match(addr)
  case @pat[0]
  when :all
    true
  when :ip
    begin
      ipaddr = IPAddr.new(addr[3])
      ipaddr = ipaddr.ipv4_mapped if @pat[1].ipv6? && ipaddr.ipv4?
    rescue ArgumentError
      return false
    end
    (@pat[1].include?(ipaddr)) ? true : false
  when :name
    (@pat[1] =~ addr[2]) ? true : false
  else
    false
  end
end


class ACL::ACLList - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class ACL::ACLList

A list of ACLEntry objects. Used to implement the allow and deny halves of an ACL

In Files

  • lib/drb/acl.rb

Parent

Object

Public Class Methods

new() click to toggle source

Creates an empty ACLList

# File lib/drb/acl.rb, line 122
def initialize
  @list = []
end

Public Instance Methods

add(str) click to toggle source

Adds str as an ACLEntry in this list

# File lib/drb/acl.rb, line 143
def add(str)
  @list.push(ACLEntry.new(str))
end
match(addr) click to toggle source

Matches addr against each ACLEntry in this list.

# File lib/drb/acl.rb, line 131
def match(addr)
  @list.each do |e|
    return true if e.match(addr)
  end
  false
end


module Abbrev - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Abbrev

Calculates the set of unique abbreviations for a given set of strings.

require 'abbrev'
require 'pp'

pp Abbrev.abbrev(['ruby', 'rules'])

Generates:

{ "rub"   =>  "ruby",
  "ruby"  =>  "ruby",
  "rul"   =>  "rules",
  "rule"  =>  "rules",
  "rules" =>  "rules" }

It also provides an array core extension, Array#abbrev.

pp %w{summer winter}.abbrev
#=> {"summe"=>"summer",
     "summ"=>"summer",
     "sum"=>"summer",
     "su"=>"summer",
     "s"=>"summer",
     "winte"=>"winter",
     "wint"=>"winter",
     "win"=>"winter",
     "wi"=>"winter",
     "w"=>"winter",
     "summer"=>"summer",
     "winter"=>"winter"}

In Files

  • lib/abbrev.rb

Public Class Methods

abbrev(words, pattern = nil) click to toggle source

Given a set of strings, calculate the set of unambiguous abbreviations for those strings, and return a hash where the keys are all the possible abbreviations and the values are the full strings.

Thus, given words is “car” and “cone”, the keys pointing to “car” would be “ca” and “car”, while those pointing to “cone” would be “co”, “con”, and “cone”.

require 'abbrev'

Abbrev.abbrev(['car', 'cone'])
#=> {"ca"=>"car", "con"=>"cone", "co"=>"cone", "car"=>"car", "cone"=>"cone"}

The optional pattern parameter is a pattern or a string. Only input strings that match the pattern or start with the string are included in the output hash.

Abbrev.abbrev(%w{car box cone}, /b/)
#=> {"bo"=>"box", "b"=>"box", "box"=>"box"}

# File lib/abbrev.rb, line 67
def abbrev(words, pattern = nil)
  table = {}
  seen = Hash.new(0)

  if pattern.is_a?(String)
    pattern = /\A#{Regexp.quote(pattern)}/  # regard as a prefix
  end

  words.each do |word|
    next if word.empty?
    word.size.downto(1) { |len|
      abbrev = word[0...len]

      next if pattern && pattern !~ abbrev

      case seen[abbrev] += 1
      when 1
        table[abbrev] = word
      when 2
        table.delete(abbrev)
      else
        break
      end
    }
  end

  words.each do |word|
    next if pattern && pattern !~ word

    table[word] = word
  end

  table
end


class Addrinfo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Addrinfo

The Addrinfo class maps struct addrinfo to ruby. This structure identifies an Internet host and a service.

In Files

  • ext/socket/raddrinfo.c
  • ext/socket/lib/socket.rb

Parent

Data

Public Class Methods

foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, &block) click to toggle source

iterates over the list of Addrinfo objects obtained by ::getaddrinfo.

Addrinfo.foreach(nil, 80) {|x| p x }
#=> #<Addrinfo: 127.0.0.1:80 TCP (:80)>
#   #<Addrinfo: 127.0.0.1:80 UDP (:80)>
#   #<Addrinfo: [::1]:80 TCP (:80)>
#   #<Addrinfo: [::1]:80 UDP (:80)>

# File ext/socket/lib/socket.rb, line 231
def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, &block)
  Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags).each(&block)
end
getaddrinfo(nodename, service, family, socktype, protocol, flags) → [addrinfo, ...] click to toggle source
getaddrinfo(nodename, service, family, socktype, protocol) → [addrinfo, ...]
getaddrinfo(nodename, service, family, socktype) → [addrinfo, ...]
getaddrinfo(nodename, service, family) → [addrinfo, ...]
getaddrinfo(nodename, service) → [addrinfo, ...]

returns a list of addrinfo objects as an array.

This method converts nodename (hostname) and service (port) to addrinfo. Since the conversion is not unique, the result is a list of addrinfo objects.

nodename or service can be nil if no conversion intended.

family, socktype and protocol are hint for preferred protocol. If the result will be used for a socket with SOCK_STREAM, SOCK_STREAM should be specified as socktype. If so, ::getaddrinfo returns addrinfo list appropriate for SOCK_STREAM. If they are omitted or nil is given, the result is not restricted.

Similarly, PF_INET6 as family restricts for IPv6.

flags should be bitwise OR of Socket::AI_??? constants such as follows. Note that the exact list of the constants depends on OS.

AI_PASSIVE      Get address to use with bind()
AI_CANONNAME    Fill in the canonical name
AI_NUMERICHOST  Prevent host name resolution
AI_NUMERICSERV  Prevent service name resolution
AI_V4MAPPED     Accept IPv4-mapped IPv6 addresses
AI_ALL          Allow all addresses
AI_ADDRCONFIG   Accept only if any address is assigned

Note that socktype should be specified whenever application knows the usage of the address. Some platform causes an error when socktype is omitted and servname is specified as an integer because some port numbers, 512 for example, are ambiguous without socktype.

Addrinfo.getaddrinfo("www.kame.net", 80, nil, :STREAM)
#=> [#<Addrinfo: 203.178.141.194:80 TCP (www.kame.net)>,
#    #<Addrinfo: [2001:200:dff:fff1:216:3eff:feb1:44d7]:80 TCP (www.kame.net)>]

static VALUE
addrinfo_s_getaddrinfo(int argc, VALUE *argv, VALUE self)
{
    VALUE node, service, family, socktype, protocol, flags;

    rb_scan_args(argc, argv, "24", &node, &service, &family, &socktype, &protocol, &flags);
    return addrinfo_list_new(node, service, family, socktype, protocol, flags);
}
ip(host) → addrinfo click to toggle source

returns an addrinfo object for IP address.

The port, socktype, protocol of the result is filled by zero. So, it is not appropriate to create a socket.

Addrinfo.ip("localhost") #=> #<Addrinfo: 127.0.0.1 (localhost)>

static VALUE
addrinfo_s_ip(VALUE self, VALUE host)
{
    VALUE ret;
    rb_addrinfo_t *rai;
    ret = addrinfo_firstonly_new(host, Qnil,
            INT2NUM(PF_UNSPEC), INT2FIX(0), INT2FIX(0), INT2FIX(0));
    rai = get_addrinfo(ret);
    rai->socktype = 0;
    rai->protocol = 0;
    return ret;
}
new(sockaddr) → addrinfo click to toggle source
new(sockaddr, family) → addrinfo
new(sockaddr, family, socktype) → addrinfo
new(sockaddr, family, socktype, protocol) → addrinfo

returns a new instance of Addrinfo. The instance contains sockaddr, family, socktype, protocol. sockaddr means struct sockaddr which can be used for connect(2), etc. family, socktype and protocol are integers which is used for arguments of socket(2).

sockaddr is specified as an array or a string. The array should be compatible to the value of IPSocket#addr or UNIXSocket#addr. The string should be struct sockaddr as generated by Socket.sockaddr_in or Socket.unpack_sockaddr_un.

sockaddr examples:

  • “AF_INET”, 46102, “localhost.localdomain”, “127.0.0.1”
  • “AF_INET6”, 42304, “ip6-localhost”, “::1”
  • “AF_UNIX”, “/tmp/sock”

  • Socket.sockaddr_in(“smtp”, “2001:DB8::1”)

  • Socket.sockaddr_in(80, “172.18.22.42”)

  • Socket.sockaddr_in(80, “www.ruby-lang.org”)

  • Socket.sockaddr_un(“/tmp/sock”)

In an AF_INET/AF_INET6 sockaddr array, the 4th element, numeric IP address, is used to construct socket address in the Addrinfo instance. If the 3rd element, textual host name, is non-nil, it is also recorded but used only for #inspect.

family is specified as an integer to specify the protocol family such as Socket::PF_INET. It can be a symbol or a string which is the constant name with or without PF_ prefix such as :INET, :INET6, :UNIX, “PF_INET”, etc. If omitted, PF_UNSPEC is assumed.

socktype is specified as an integer to specify the socket type such as Socket::SOCK_STREAM. It can be a symbol or a string which is the constant name with or without SOCK_ prefix such as :STREAM, :DGRAM, :RAW, “SOCK_STREAM”, etc. If omitted, 0 is assumed.

protocol is specified as an integer to specify the protocol such as Socket::IPPROTO_TCP. It must be an integer, unlike family and socktype. If omitted, 0 is assumed. Note that 0 is reasonable value for most protocols, except raw socket.

static VALUE
addrinfo_initialize(int argc, VALUE *argv, VALUE self)
{
    rb_addrinfo_t *rai;
    VALUE sockaddr_arg, sockaddr_ary, pfamily, socktype, protocol;
    int i_pfamily, i_socktype, i_protocol;
    struct sockaddr *sockaddr_ptr;
    socklen_t sockaddr_len;
    VALUE canonname = Qnil, inspectname = Qnil;

    if (check_addrinfo(self))
        rb_raise(rb_eTypeError, "already initialized socket address");
    DATA_PTR(self) = rai = alloc_addrinfo();

    rb_scan_args(argc, argv, "13", &sockaddr_arg, &pfamily, &socktype, &protocol);

    i_pfamily = NIL_P(pfamily) ? PF_UNSPEC : rsock_family_arg(pfamily);
    i_socktype = NIL_P(socktype) ? 0 : rsock_socktype_arg(socktype);
    i_protocol = NIL_P(protocol) ? 0 : NUM2INT(protocol);

    sockaddr_ary = rb_check_array_type(sockaddr_arg);
    if (!NIL_P(sockaddr_ary)) {
        VALUE afamily = rb_ary_entry(sockaddr_ary, 0);
        int af;
        StringValue(afamily);
        if (rsock_family_to_int(RSTRING_PTR(afamily), RSTRING_LEN(afamily), &af) == -1)
            rb_raise(rb_eSocket, "unknown address family: %s", StringValueCStr(afamily));
        switch (af) {
          case AF_INET: /* ["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"] */
#ifdef INET6
          case AF_INET6: /* ["AF_INET6", 42304, "ip6-localhost", "::1"] */
#endif
          {
            VALUE service = rb_ary_entry(sockaddr_ary, 1);
            VALUE nodename = rb_ary_entry(sockaddr_ary, 2);
            VALUE numericnode = rb_ary_entry(sockaddr_ary, 3);
            int flags;

            service = INT2NUM(NUM2INT(service));
            if (!NIL_P(nodename))
                StringValue(nodename);
            StringValue(numericnode);
            flags = AI_NUMERICHOST;
#ifdef AI_NUMERICSERV
            flags |= AI_NUMERICSERV;
#endif

            init_addrinfo_getaddrinfo(rai, numericnode, service,
                    INT2NUM(i_pfamily ? i_pfamily : af), INT2NUM(i_socktype), INT2NUM(i_protocol),
                    INT2NUM(flags),
                    nodename, service);
            break;
          }

#ifdef HAVE_SYS_UN_H
          case AF_UNIX: /* ["AF_UNIX", "/tmp/sock"] */
          {
            VALUE path = rb_ary_entry(sockaddr_ary, 1);
            StringValue(path);
            init_unix_addrinfo(rai, path, SOCK_STREAM);
            break;
          }
#endif

          default:
            rb_raise(rb_eSocket, "unexpected address family");
        }
    }
    else {
        StringValue(sockaddr_arg);
        sockaddr_ptr = (struct sockaddr *)RSTRING_PTR(sockaddr_arg);
        sockaddr_len = RSTRING_LENINT(sockaddr_arg);
        init_addrinfo(rai, sockaddr_ptr, sockaddr_len,
                      i_pfamily, i_socktype, i_protocol,
                      canonname, inspectname);
    }

    return self;
}
tcp(host, port) → addrinfo click to toggle source

returns an addrinfo object for TCP address.

Addrinfo.tcp("localhost", "smtp") #=> #<Addrinfo: 127.0.0.1:25 TCP (localhost:smtp)>

static VALUE
addrinfo_s_tcp(VALUE self, VALUE host, VALUE port)
{
    return addrinfo_firstonly_new(host, port,
            INT2NUM(PF_UNSPEC), INT2NUM(SOCK_STREAM), INT2NUM(IPPROTO_TCP), INT2FIX(0));
}
udp(host, port) → addrinfo click to toggle source

returns an addrinfo object for UDP address.

Addrinfo.udp("localhost", "daytime") #=> #<Addrinfo: 127.0.0.1:13 UDP (localhost:daytime)>

static VALUE
addrinfo_s_udp(VALUE self, VALUE host, VALUE port)
{
    return addrinfo_firstonly_new(host, port,
            INT2NUM(PF_UNSPEC), INT2NUM(SOCK_DGRAM), INT2NUM(IPPROTO_UDP), INT2FIX(0));
}
unix(path [, socktype]) → addrinfo click to toggle source

returns an addrinfo object for UNIX socket address.

socktype specifies the socket type. If it is omitted, :STREAM is used.

Addrinfo.unix("/tmp/sock")         #=> #<Addrinfo: /tmp/sock SOCK_STREAM>
Addrinfo.unix("/tmp/sock", :DGRAM) #=> #<Addrinfo: /tmp/sock SOCK_DGRAM>

static VALUE
addrinfo_s_unix(int argc, VALUE *argv, VALUE self)
{
    VALUE path, vsocktype, addr;
    int socktype;
    rb_addrinfo_t *rai;

    rb_scan_args(argc, argv, "11", &path, &vsocktype);

    if (NIL_P(vsocktype))
        socktype = SOCK_STREAM;
    else
        socktype = rsock_socktype_arg(vsocktype);

    addr = addrinfo_s_allocate(rb_cAddrinfo);
    DATA_PTR(addr) = rai = alloc_addrinfo();
    init_unix_addrinfo(rai, path, socktype);
    OBJ_INFECT(addr, path);
    return addr;
}

Public Instance Methods

afamily → integer click to toggle source

returns the address family as an integer.

Addrinfo.tcp("localhost", 80).afamily == Socket::AF_INET #=> true

static VALUE
addrinfo_afamily(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    return INT2NUM(ai_get_afamily(rai));
}
bind() { |sock| ... } click to toggle source

creates a socket bound to self.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.udp("0.0.0.0", 9981).bind {|s|
  s.local_address.connect {|s| s.send "hello", 0 }
  p s.recv(10) #=> "hello"
}

# File ext/socket/lib/socket.rb, line 179
def bind
  sock = Socket.new(self.pfamily, self.socktype, self.protocol)
  begin
    sock.ipv6only! if self.ipv6?
    sock.setsockopt(:SOCKET, :REUSEADDR, 1)
    sock.bind(self)
  rescue Exception
    sock.close
    raise
  end
  if block_given?
    begin
      yield sock
    ensure
      sock.close if !sock.closed?
    end
  else
    sock
  end
end
canonname → string or nil click to toggle source

returns the canonical name as an string.

nil is returned if no canonical name.

The canonical name is set by ::getaddrinfo when AI_CANONNAME is specified.

list = Addrinfo.getaddrinfo("www.ruby-lang.org", 80, :INET, :STREAM, nil, Socket::AI_CANONNAME)
p list[0] #=> #<Addrinfo: 221.186.184.68:80 TCP carbon.ruby-lang.org (www.ruby-lang.org)>
p list[0].canonname #=> "carbon.ruby-lang.org"

static VALUE
addrinfo_canonname(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    return rai->canonname;
}
connect([opts]) {|socket| ... } click to toggle source
connect([opts])

creates a socket connected to the address of self.

The optional argument opts is options represented by a hash. opts may have following options:

:timeout

specify the timeout in seconds.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.tcp("www.ruby-lang.org", 80).connect {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}

# File ext/socket/lib/socket.rb, line 139
def connect(opts={}, &block)
  connect_internal(nil, opts[:timeout], &block)
end
connect_from([local_addr_args], [opts]) {|socket| ... } click to toggle source
connect_from([local_addr_args], [opts])

creates a socket connected to the address of self.

If one or more arguments given as local_addr_args, it is used as the local address of the socket. local_addr_args is given for #family_addrinfo to obtain actual address.

If local_addr_args is not given, the local address of the socket is not bound.

The optional last argument opts is options represented by a hash. opts may have following options:

:timeout

specify the timeout in seconds.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.tcp("www.ruby-lang.org", 80).connect_from("0.0.0.0", 4649) {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}

# Addrinfo object can be taken for the argument.
Addrinfo.tcp("www.ruby-lang.org", 80).connect_from(Addrinfo.tcp("0.0.0.0", 4649)) {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}

# File ext/socket/lib/socket.rb, line 114
def connect_from(*args, &block)
  opts = Hash === args.last ? args.pop : {}
  local_addr_args = args
  connect_internal(family_addrinfo(*local_addr_args), opts[:timeout], &block)
end
connect_to([remote_addr_args], [opts]) {|socket| ... } click to toggle source
connect_to([remote_addr_args], [opts])

creates a socket connected to remote_addr_args and bound to self.

The optional last argument opts is options represented by a hash. opts may have following options:

:timeout

specify the timeout in seconds.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.tcp("0.0.0.0", 4649).connect_to("www.ruby-lang.org", 80) {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}

# File ext/socket/lib/socket.rb, line 162
def connect_to(*args, &block)
  opts = Hash === args.last ? args.pop : {}
  remote_addr_args = args
  remote_addrinfo = family_addrinfo(*remote_addr_args)
  remote_addrinfo.send(:connect_internal, self, opts[:timeout], &block)
end
family_addrinfo(*args) click to toggle source

creates an Addrinfo object from the arguments.

The arguments are interpreted as similar to self.

Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("www.ruby-lang.org", 80)
#=> #<Addrinfo: 221.186.184.68:80 TCP (www.ruby-lang.org:80)>

Addrinfo.unix("/tmp/sock").family_addrinfo("/tmp/sock2")
#=> #<Addrinfo: /tmp/sock2 SOCK_STREAM>

# File ext/socket/lib/socket.rb, line 14
def family_addrinfo(*args)
  if args.empty?
    raise ArgumentError, "no address specified"
  elsif Addrinfo === args.first
    raise ArgumentError, "too many arguments" if args.length != 1
    addrinfo = args.first
    if (self.pfamily != addrinfo.pfamily) ||
       (self.socktype != addrinfo.socktype)
      raise ArgumentError, "Addrinfo type mismatch"
    end
    addrinfo
  elsif self.ip?
    raise ArgumentError, "IP address needs host and port but #{args.length} arguments given" if args.length != 2
    host, port = args
    Addrinfo.getaddrinfo(host, port, self.pfamily, self.socktype, self.protocol)[0]
  elsif self.unix?
    raise ArgumentError, "UNIX socket needs single path argument but #{args.length} arguments given" if args.length != 1
    path, = args
    Addrinfo.unix(path)
  else
    raise ArgumentError, "unexpected family"
  end
end
getnameinfo → [nodename, service] click to toggle source
getnameinfo(flags) → [nodename, service]

returns nodename and service as a pair of strings. This converts struct sockaddr in addrinfo to textual representation.

flags should be bitwise OR of Socket::NI_??? constants.

Addrinfo.tcp("127.0.0.1", 80).getnameinfo #=> ["localhost", "www"]

Addrinfo.tcp("127.0.0.1", 80).getnameinfo(Socket::NI_NUMERICSERV)
#=> ["localhost", "80"]

static VALUE
addrinfo_getnameinfo(int argc, VALUE *argv, VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    VALUE vflags;
    char hbuf[1024], pbuf[1024];
    int flags, error;

    rb_scan_args(argc, argv, "01", &vflags);

    flags = NIL_P(vflags) ? 0 : NUM2INT(vflags);

    if (rai->socktype == SOCK_DGRAM)
        flags |= NI_DGRAM;

    error = getnameinfo((struct sockaddr *)&rai->addr, rai->sockaddr_len,
                        hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf),
                        flags);
    if (error) {
        rsock_raise_socket_error("getnameinfo", error);
    }

    return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf));
}
inspect → string click to toggle source

returns a string which shows addrinfo in human-readable form.

Addrinfo.tcp("localhost", 80).inspect #=> "#<Addrinfo: 127.0.0.1:80 TCP (localhost)>"
Addrinfo.unix("/tmp/sock").inspect    #=> "#<Addrinfo: /tmp/sock SOCK_STREAM>"

static VALUE
addrinfo_inspect(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    int internet_p;
    VALUE ret;

    ret = rb_sprintf("#<%s: ", rb_obj_classname(self));

    inspect_sockaddr(self, ret);

    if (rai->pfamily && ai_get_afamily(rai) != rai->pfamily) {
        ID id = rsock_intern_protocol_family(rai->pfamily);
        if (id)
            rb_str_catf(ret, " %s", rb_id2name(id));
        else
            rb_str_catf(ret, " PF_\?\?\?(%d)", rai->pfamily);
    }

    internet_p = rai->pfamily == PF_INET;
#ifdef INET6
    internet_p = internet_p || rai->pfamily == PF_INET6;
#endif
    if (internet_p && rai->socktype == SOCK_STREAM &&
        (rai->protocol == 0 || rai->protocol == IPPROTO_TCP)) {
        rb_str_cat2(ret, " TCP");
    }
    else if (internet_p && rai->socktype == SOCK_DGRAM &&
        (rai->protocol == 0 || rai->protocol == IPPROTO_UDP)) {
        rb_str_cat2(ret, " UDP");
    }
    else {
        if (rai->socktype) {
            ID id = rsock_intern_socktype(rai->socktype);
            if (id)
                rb_str_catf(ret, " %s", rb_id2name(id));
            else
                rb_str_catf(ret, " SOCK_\?\?\?(%d)", rai->socktype);
        }

        if (rai->protocol) {
            if (internet_p) {
                ID id = rsock_intern_ipproto(rai->protocol);
                if (id)
                    rb_str_catf(ret, " %s", rb_id2name(id));
                else
                    goto unknown_protocol;
            }
            else {
              unknown_protocol:
                rb_str_catf(ret, " UNKNOWN_PROTOCOL(%d)", rai->protocol);
            }
        }
    }

    if (!NIL_P(rai->canonname)) {
        VALUE name = rai->canonname;
        rb_str_catf(ret, " %s", StringValueCStr(name));
    }

    if (!NIL_P(rai->inspectname)) {
        VALUE name = rai->inspectname;
        rb_str_catf(ret, " (%s)", StringValueCStr(name));
    }

    rb_str_buf_cat2(ret, ">");
    return ret;
}
inspect_sockaddr → string click to toggle source

returns a string which shows the sockaddr in addrinfo with human-readable form.

Addrinfo.tcp("localhost", 80).inspect_sockaddr     #=> "127.0.0.1:80"
Addrinfo.tcp("ip6-localhost", 80).inspect_sockaddr #=> "[::1]:80"
Addrinfo.unix("/tmp/sock").inspect_sockaddr        #=> "/tmp/sock"

static VALUE
addrinfo_inspect_sockaddr(VALUE self)
{
    return inspect_sockaddr(self, rb_str_new("", 0));
}
ip? → true or false click to toggle source

returns true if addrinfo is internet (IPv4/IPv6) address. returns false otherwise.

Addrinfo.tcp("127.0.0.1", 80).ip? #=> true
Addrinfo.tcp("::1", 80).ip?       #=> true
Addrinfo.unix("/tmp/sock").ip?    #=> false

static VALUE
addrinfo_ip_p(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    int family = ai_get_afamily(rai);
    return IS_IP_FAMILY(family) ? Qtrue : Qfalse;
}
ip_address → string click to toggle source

Returns the IP address as a string.

Addrinfo.tcp("127.0.0.1", 80).ip_address    #=> "127.0.0.1"
Addrinfo.tcp("::1", 80).ip_address          #=> "::1"

static VALUE
addrinfo_ip_address(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    int family = ai_get_afamily(rai);
    VALUE vflags;
    VALUE ret;

    if (!IS_IP_FAMILY(family))
        rb_raise(rb_eSocket, "need IPv4 or IPv6 address");

    vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV);
    ret = addrinfo_getnameinfo(1, &vflags, self);
    return rb_ary_entry(ret, 0);
}
ip_port → port click to toggle source

Returns the port number as an integer.

Addrinfo.tcp("127.0.0.1", 80).ip_port    #=> 80
Addrinfo.tcp("::1", 80).ip_port          #=> 80

static VALUE
addrinfo_ip_port(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    int family = ai_get_afamily(rai);
    int port;

    if (!IS_IP_FAMILY(family)) {
      bad_family:
#ifdef AF_INET6
        rb_raise(rb_eSocket, "need IPv4 or IPv6 address");
#else
        rb_raise(rb_eSocket, "need IPv4 address");
#endif
    }

    switch (family) {
      case AF_INET:
        if (rai->sockaddr_len != sizeof(struct sockaddr_in))
            rb_raise(rb_eSocket, "unexpected sockaddr size for IPv4");
        port = ntohs(((struct sockaddr_in *)&rai->addr)->sin_port);
        break;

#ifdef AF_INET6
      case AF_INET6:
        if (rai->sockaddr_len != sizeof(struct sockaddr_in6))
            rb_raise(rb_eSocket, "unexpected sockaddr size for IPv6");
        port = ntohs(((struct sockaddr_in6 *)&rai->addr)->sin6_port);
        break;
#endif

      default:
        goto bad_family;
    }

    return INT2NUM(port);
}
ip_unpack → [addr, port] click to toggle source

Returns the IP address and port number as 2-element array.

Addrinfo.tcp("127.0.0.1", 80).ip_unpack    #=> ["127.0.0.1", 80]
Addrinfo.tcp("::1", 80).ip_unpack          #=> ["::1", 80]

static VALUE
addrinfo_ip_unpack(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    int family = ai_get_afamily(rai);
    VALUE vflags;
    VALUE ret, portstr;

    if (!IS_IP_FAMILY(family))
        rb_raise(rb_eSocket, "need IPv4 or IPv6 address");

    vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV);
    ret = addrinfo_getnameinfo(1, &vflags, self);
    portstr = rb_ary_entry(ret, 1);
    rb_ary_store(ret, 1, INT2NUM(atoi(StringValueCStr(portstr))));
    return ret;
}
ipv4? → true or false click to toggle source

returns true if addrinfo is IPv4 address. returns false otherwise.

Addrinfo.tcp("127.0.0.1", 80).ipv4? #=> true
Addrinfo.tcp("::1", 80).ipv4?       #=> false
Addrinfo.unix("/tmp/sock").ipv4?    #=> false

static VALUE
addrinfo_ipv4_p(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    return ai_get_afamily(rai) == AF_INET ? Qtrue : Qfalse;
}
ipv4_loopback?() click to toggle source

Returns true for IPv4 loopback address (127.0.0.0/8). It returns false otherwise.

static VALUE
addrinfo_ipv4_loopback_p(VALUE self)
{
    uint32_t a;
    if (!extract_in_addr(self, &a)) return Qfalse;
    if ((a & 0xff000000) == 0x7f000000) /* 127.0.0.0/8 */
        return Qtrue;
    return Qfalse;
}
ipv4_multicast?() click to toggle source

Returns true for IPv4 multicast address (224.0.0.0/4). It returns false otherwise.

static VALUE
addrinfo_ipv4_multicast_p(VALUE self)
{
    uint32_t a;
    if (!extract_in_addr(self, &a)) return Qfalse;
    if ((a & 0xf0000000) == 0xe0000000) /* 224.0.0.0/4 */
        return Qtrue;
    return Qfalse;
}
ipv4_private?() click to toggle source

Returns true for IPv4 private address (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). It returns false otherwise.

static VALUE
addrinfo_ipv4_private_p(VALUE self)
{
    uint32_t a;
    if (!extract_in_addr(self, &a)) return Qfalse;
    if ((a & 0xff000000) == 0x0a000000 || /* 10.0.0.0/8 */
        (a & 0xfff00000) == 0xac100000 || /* 172.16.0.0/12 */
        (a & 0xffff0000) == 0xc0a80000)   /* 192.168.0.0/16 */
        return Qtrue;
    return Qfalse;
}
ipv6? → true or false click to toggle source

returns true if addrinfo is IPv6 address. returns false otherwise.

Addrinfo.tcp("127.0.0.1", 80).ipv6? #=> false
Addrinfo.tcp("::1", 80).ipv6?       #=> true
Addrinfo.unix("/tmp/sock").ipv6?    #=> false

static VALUE
addrinfo_ipv6_p(VALUE self)
{
#ifdef AF_INET6
    rb_addrinfo_t *rai = get_addrinfo(self);
    return ai_get_afamily(rai) == AF_INET6 ? Qtrue : Qfalse;
#else
    return Qfalse;
#endif
}
ipv6_linklocal?() click to toggle source

Returns true for IPv6 link local address (ff80::/10). It returns false otherwise.

static VALUE
addrinfo_ipv6_linklocal_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_LINKLOCAL(addr)) return Qtrue;
    return Qfalse;
}
ipv6_loopback?() click to toggle source

Returns true for IPv6 loopback address (::1). It returns false otherwise.

static VALUE
addrinfo_ipv6_loopback_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_LOOPBACK(addr)) return Qtrue;
    return Qfalse;
}
ipv6_mc_global?() click to toggle source

Returns true for IPv6 multicast global scope address. It returns false otherwise.

static VALUE
addrinfo_ipv6_mc_global_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_MC_GLOBAL(addr)) return Qtrue;
    return Qfalse;
}
ipv6_mc_linklocal?() click to toggle source

Returns true for IPv6 multicast link-local scope address. It returns false otherwise.

static VALUE
addrinfo_ipv6_mc_linklocal_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_MC_LINKLOCAL(addr)) return Qtrue;
    return Qfalse;
}
ipv6_mc_nodelocal?() click to toggle source

Returns true for IPv6 multicast node-local scope address. It returns false otherwise.

static VALUE
addrinfo_ipv6_mc_nodelocal_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_MC_NODELOCAL(addr)) return Qtrue;
    return Qfalse;
}
ipv6_mc_orglocal?() click to toggle source

Returns true for IPv6 multicast organization-local scope address. It returns false otherwise.

static VALUE
addrinfo_ipv6_mc_orglocal_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_MC_ORGLOCAL(addr)) return Qtrue;
    return Qfalse;
}
ipv6_mc_sitelocal?() click to toggle source

Returns true for IPv6 multicast site-local scope address. It returns false otherwise.

static VALUE
addrinfo_ipv6_mc_sitelocal_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_MC_SITELOCAL(addr)) return Qtrue;
    return Qfalse;
}
ipv6_multicast?() click to toggle source

Returns true for IPv6 multicast address (ff00::/8). It returns false otherwise.

static VALUE
addrinfo_ipv6_multicast_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_MULTICAST(addr)) return Qtrue;
    return Qfalse;
}
ipv6_sitelocal?() click to toggle source

Returns true for IPv6 site local address (ffc0::/10). It returns false otherwise.

static VALUE
addrinfo_ipv6_sitelocal_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_SITELOCAL(addr)) return Qtrue;
    return Qfalse;
}
ipv6_to_ipv4() click to toggle source

Returns IPv4 address of IPv4 mapped/compatible IPv6 address. It returns nil if self is not IPv4 mapped/compatible IPv6 address.

Addrinfo.ip("::192.0.2.3").ipv6_to_ipv4      #=> #<Addrinfo: 192.0.2.3>
Addrinfo.ip("::ffff:192.0.2.3").ipv6_to_ipv4 #=> #<Addrinfo: 192.0.2.3>
Addrinfo.ip("::1").ipv6_to_ipv4              #=> nil
Addrinfo.ip("192.0.2.3").ipv6_to_ipv4        #=> nil
Addrinfo.unix("/tmp/sock").ipv6_to_ipv4      #=> nil

static VALUE
addrinfo_ipv6_to_ipv4(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    struct in6_addr *addr;
    int family = ai_get_afamily(rai);
    if (family != AF_INET6) return Qnil;
    addr = &((struct sockaddr_in6 *)&rai->addr)->sin6_addr;
    if (IN6_IS_ADDR_V4MAPPED(addr) || IN6_IS_ADDR_V4COMPAT(addr)) {
        struct sockaddr_in sin4;
        MEMZERO(&sin4, struct sockaddr_in, 1);
        sin4.sin_family = AF_INET;
        SET_SIN_LEN(&sin4, sizeof(sin4));
        memcpy(&sin4.sin_addr, (char*)addr + sizeof(*addr) - sizeof(sin4.sin_addr), sizeof(sin4.sin_addr));
        return rsock_addrinfo_new((struct sockaddr *)&sin4, (socklen_t)sizeof(sin4),
                                  PF_INET, rai->socktype, rai->protocol,
                                  rai->canonname, rai->inspectname);
    }
    else {
        return Qnil;
    }
}
ipv6_unique_local?() click to toggle source

Returns true for IPv6 unique local address (fc00::/7, RFC4193). It returns false otherwise.

static VALUE
addrinfo_ipv6_unique_local_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_UNIQUE_LOCAL(addr)) return Qtrue;
    return Qfalse;
}
ipv6_unspecified?() click to toggle source

Returns true for IPv6 unspecified address (::). It returns false otherwise.

static VALUE
addrinfo_ipv6_unspecified_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_UNSPECIFIED(addr)) return Qtrue;
    return Qfalse;
}
ipv6_v4compat?() click to toggle source

Returns true for IPv4-compatible IPv6 address (::/80). It returns false otherwise.

static VALUE
addrinfo_ipv6_v4compat_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_V4COMPAT(addr)) return Qtrue;
    return Qfalse;
}
ipv6_v4mapped?() click to toggle source

Returns true for IPv4-mapped IPv6 address (::ffff:0:0/80). It returns false otherwise.

static VALUE
addrinfo_ipv6_v4mapped_p(VALUE self)
{
    struct in6_addr *addr = extract_in6_addr(self);
    if (addr && IN6_IS_ADDR_V4MAPPED(addr)) return Qtrue;
    return Qfalse;
}
listen(backlog=Socket::SOMAXCONN) { |sock| ... } click to toggle source

creates a listening socket bound to self.

# File ext/socket/lib/socket.rb, line 201
def listen(backlog=Socket::SOMAXCONN)
  sock = Socket.new(self.pfamily, self.socktype, self.protocol)
  begin
    sock.ipv6only! if self.ipv6?
    sock.setsockopt(:SOCKET, :REUSEADDR, 1)
    sock.bind(self)
    sock.listen(backlog)
  rescue Exception
    sock.close
    raise
  end
  if block_given?
    begin
      yield sock
    ensure
      sock.close if !sock.closed?
    end
  else
    sock
  end
end
pfamily → integer click to toggle source

returns the protocol family as an integer.

Addrinfo.tcp("localhost", 80).pfamily == Socket::PF_INET #=> true

static VALUE
addrinfo_pfamily(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    return INT2NUM(rai->pfamily);
}
protocol → integer click to toggle source

returns the socket type as an integer.

Addrinfo.tcp("localhost", 80).protocol == Socket::IPPROTO_TCP #=> true

static VALUE
addrinfo_protocol(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    return INT2NUM(rai->protocol);
}
socktype → integer click to toggle source

returns the socket type as an integer.

Addrinfo.tcp("localhost", 80).socktype == Socket::SOCK_STREAM #=> true

static VALUE
addrinfo_socktype(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    return INT2NUM(rai->socktype);
}
to_sockaddr → string click to toggle source
to_s → string

returns the socket address as packed struct sockaddr string.

Addrinfo.tcp("localhost", 80).to_sockaddr
#=> "\x02\x00\x00P\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"

static VALUE
addrinfo_to_sockaddr(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    VALUE ret;
    ret = rb_str_new((char*)&rai->addr, rai->sockaddr_len);
    OBJ_INFECT(ret, self);
    return ret;
}
to_sockaddr → string click to toggle source
to_s → string

returns the socket address as packed struct sockaddr string.

Addrinfo.tcp("localhost", 80).to_sockaddr
#=> "\x02\x00\x00P\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"

static VALUE
addrinfo_to_sockaddr(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    VALUE ret;
    ret = rb_str_new((char*)&rai->addr, rai->sockaddr_len);
    OBJ_INFECT(ret, self);
    return ret;
}
unix? → true or false click to toggle source

returns true if addrinfo is UNIX address. returns false otherwise.

Addrinfo.tcp("127.0.0.1", 80).unix? #=> false
Addrinfo.tcp("::1", 80).unix?       #=> false
Addrinfo.unix("/tmp/sock").unix?    #=> true

static VALUE
addrinfo_unix_p(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
#ifdef AF_UNIX
    return ai_get_afamily(rai) == AF_UNIX ? Qtrue : Qfalse;
#else
    return Qfalse;
#endif
}
unix_path → path click to toggle source

Returns the socket path as a string.

Addrinfo.unix("/tmp/sock").unix_path       #=> "/tmp/sock"

static VALUE
addrinfo_unix_path(VALUE self)
{
    rb_addrinfo_t *rai = get_addrinfo(self);
    int family = ai_get_afamily(rai);
    struct sockaddr_un *addr;
    char *s, *e;

    if (family != AF_UNIX)
        rb_raise(rb_eSocket, "need AF_UNIX address");

    addr = (struct sockaddr_un *)&rai->addr;

    s = addr->sun_path;
    e = (char*)addr + rai->sockaddr_len;
    if (e < s)
        rb_raise(rb_eSocket, "too short AF_UNIX address: %"PRIuSIZE" bytes given for minimum %"PRIuSIZE" bytes.",
            (size_t)rai->sockaddr_len, (size_t)(s - (char *)addr));
    if (addr->sun_path + sizeof(addr->sun_path) < e)
        rb_raise(rb_eSocket,
            "too long AF_UNIX path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
            (size_t)(e - addr->sun_path), sizeof(addr->sun_path));
    while (s < e && *(e-1) == '\0')
        e--;
    return rb_str_new(s, e-s);
}


class Array - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Array

In Files

  • lib/abbrev.rb
  • lib/csv.rb
  • lib/mkmf.rb
  • lib/pp.rb
  • lib/rexml/xpath_parser.rb
  • lib/shellwords.rb

Parent

Object

Public Instance Methods

abbrev(pattern = nil) click to toggle source

Calculates the set of unambiguous abbreviations for the strings in self.

require 'abbrev'
%w{ car cone }.abbrev
#=> {"ca" => "car", "con"=>"cone", "co" => "cone",
     "car"=>"car", "cone" => "cone"}

The optional pattern parameter is a pattern or a string. Only input strings that match the pattern or start with the string are included in the output hash.

%w{ fast boat day }.abbrev(/^.a/)
#=> {"fas"=>"fast", "fa"=>"fast", "da"=>"day",
     "fast"=>"fast", "day"=>"day"}

See also Abbrev.abbrev

# File lib/abbrev.rb, line 123
def abbrev(pattern = nil)
  Abbrev::abbrev(self, pattern)
end
dclone() click to toggle source

provides a unified clone operation, for REXML::XPathParser to use across multiple Object+ types

# File lib/rexml/xpath_parser.rb, line 32
def dclone
  klone = self.clone
  klone.clear
  self.each{|v| klone << v.dclone}
  klone
end
pretty_print(q) click to toggle source
# File lib/pp.rb, line 328
def pretty_print(q)
  q.group(1, '[', ']') {
    q.seplist(self) {|v|
      q.pp v
    }
  }
end
pretty_print_cycle(q) click to toggle source
# File lib/pp.rb, line 336
def pretty_print_cycle(q)
  q.text(empty? ? '[]' : '[...]')
end
shelljoin → string click to toggle source

Builds a command line string from an argument list array joining all elements escaped for Bourne shell and separated by a space.

See Shellwords.shelljoin for details.

# File lib/shellwords.rb, line 212
def shelljoin
  Shellwords.join(self)
end


module Base64 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Base64

The Base64 module provides for the encoding (encode64, strict_encode64, urlsafe_encode64) and decoding (decode64, strict_decode64, urlsafe_decode64) of binary data using a Base64 representation.

Example

A simple encoding and decoding.

require "base64"

enc   = Base64.encode64('Send reinforcements')
                    # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n"
plain = Base64.decode64(enc)
                    # -> "Send reinforcements"

The purpose of using base64 to encode data is that it translates any binary data into purely printable characters.

In Files

  • lib/base64.rb

Public Instance Methods

decode64(str) click to toggle source

Returns the Base64-decoded version of str. This method complies with RFC 2045. Characters outside the base alphabet are ignored.

require 'base64'
str = 'VGhpcyBpcyBsaW5lIG9uZQpUaGlzIG' +
      'lzIGxpbmUgdHdvClRoaXMgaXMgbGlu' +
      'ZSB0aHJlZQpBbmQgc28gb24uLi4K'
puts Base64.decode64(str)

Generates:

This is line one
This is line two
This is line three
And so on...
# File lib/base64.rb, line 57
def decode64(str)
  str.unpack("m").first
end
encode64(bin) click to toggle source

Returns the Base64-encoded version of bin. This method complies with RFC 2045. Line feeds are added to every 60 encoded charactors.

require 'base64'
Base64.encode64("Now is the time for all good coders\nto learn Ruby")

Generates:

Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g
UnVieQ==
# File lib/base64.rb, line 37
def encode64(bin)
  [bin].pack("m")
end
strict_decode64(str) click to toggle source

Returns the Base64-decoded version of str. This method complies with RFC 4648. ArgumentError is raised if str is incorrectly padded or contains non-alphabet characters. Note that CR or LF are also rejected.

# File lib/base64.rb, line 72
def strict_decode64(str)
  str.unpack("m0").first
end
strict_encode64(bin) click to toggle source

Returns the Base64-encoded version of bin. This method complies with RFC 4648. No line feeds are added.

# File lib/base64.rb, line 64
def strict_encode64(bin)
  [bin].pack("m0")
end
urlsafe_decode64(str) click to toggle source

Returns the Base64-decoded version of str. This method complies with “Base 64 Encoding with URL and Filename Safe Alphabet'' in RFC 4648. The alphabet uses '-' instead of '+' and '_' instead of '/'.

# File lib/base64.rb, line 88
def urlsafe_decode64(str)
  strict_decode64(str.tr("-_", "+/"))
end
urlsafe_encode64(bin) click to toggle source

Returns the Base64-encoded version of bin. This method complies with “Base 64 Encoding with URL and Filename Safe Alphabet'' in RFC 4648. The alphabet uses '-' instead of '+' and '_' instead of '/'.

# File lib/base64.rb, line 80
def urlsafe_encode64(bin)
  strict_encode64(bin).tr("+/", "-_")
end


class BasicSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class BasicSocket

BasicSocket is the super class for all the Socket classes.

In Files

  • ext/socket/basicsocket.c
  • ext/socket/lib/socket.rb

Parent

IO

Public Class Methods

do_not_reverse_lookup → true or false click to toggle source

Gets the global ::do_not_reverse_lookup flag.

BasicSocket.do_not_reverse_lookup  #=> false

static VALUE
bsock_do_not_rev_lookup(void)
{
    return rsock_do_not_reverse_lookup?Qtrue:Qfalse;
}
do_not_reverse_lookup = bool click to toggle source

Sets the global ::do_not_reverse_lookup flag.

The flag is used for initial value of ::do_not_reverse_lookup for each socket.

s1 = TCPSocket.new("localhost", 80)
p s1.do_not_reverse_lookup                 #=> true
BasicSocket.do_not_reverse_lookup = false
s2 = TCPSocket.new("localhost", 80)
p s2.do_not_reverse_lookup                 #=> false
p s1.do_not_reverse_lookup                 #=> true

static VALUE
bsock_do_not_rev_lookup_set(VALUE self, VALUE val)
{
    rb_secure(4);
    rsock_do_not_reverse_lookup = RTEST(val);
    return val;
}
for_fd(fd) → basicsocket click to toggle source

Returns a socket object which contains the file descriptor, fd.

# If invoked by inetd, STDIN/STDOUT/STDERR is a socket.
STDIN_SOCK = Socket.for_fd(STDIN.fileno)
p STDIN_SOCK.remote_address
static VALUE
bsock_s_for_fd(VALUE klass, VALUE fd)
{
    rb_io_t *fptr;
    VALUE sock = rsock_init_sock(rb_obj_alloc(klass), NUM2INT(fd));

    GetOpenFile(sock, fptr);

    return sock;
}

Public Instance Methods

close_read → nil click to toggle source

Disallows further read using shutdown system call.

s1, s2 = UNIXSocket.pair
s1.close_read
s2.puts #=> Broken pipe (Errno::EPIPE)

static VALUE
bsock_close_read(VALUE sock)
{
    rb_io_t *fptr;

    if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
        rb_raise(rb_eSecurityError, "Insecure: can't close socket");
    }
    GetOpenFile(sock, fptr);
    shutdown(fptr->fd, 0);
    if (!(fptr->mode & FMODE_WRITABLE)) {
        return rb_io_close(sock);
    }
    fptr->mode &= ~FMODE_READABLE;

    return Qnil;
}
close_write → nil click to toggle source

Disallows further write using shutdown system call.

UNIXSocket.pair {|s1, s2|
  s1.print "ping"
  s1.close_write
  p s2.read        #=> "ping"
  s2.print "pong"
  s2.close
  p s1.read        #=> "pong"
}

static VALUE
bsock_close_write(VALUE sock)
{
    rb_io_t *fptr;

    if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
        rb_raise(rb_eSecurityError, "Insecure: can't close socket");
    }
    GetOpenFile(sock, fptr);
    if (!(fptr->mode & FMODE_READABLE)) {
        return rb_io_close(sock);
    }
    shutdown(fptr->fd, 1);
    fptr->mode &= ~FMODE_WRITABLE;

    return Qnil;
}
connect_address() click to toggle source

Returns an address of the socket suitable for connect in the local machine.

This method returns self.#local_address, except following condition.

  • IPv4 unspecified address (0.0.0.0) is replaced by IPv4 loopback address (127.0.0.1).

  • IPv6 unspecified address (::) is replaced by IPv6 loopback address (::1).

If the local address is not suitable for connect, SocketError is raised. IPv4 and IPv6 address which port is 0 is not suitable for connect. Unix domain socket which has no path is not suitable for connect.

Addrinfo.tcp("0.0.0.0", 0).listen {|serv|
  p serv.connect_address #=> #<Addrinfo: 127.0.0.1:53660 TCP>
  serv.connect_address.connect {|c|
    s, _ = serv.accept
    p [c, s] #=> [#<Socket:fd 4>, #<Socket:fd 6>]
  }
}

# File ext/socket/lib/socket.rb, line 256
def connect_address
  addr = local_address
  afamily = addr.afamily
  if afamily == Socket::AF_INET
    raise SocketError, "unbound IPv4 socket" if addr.ip_port == 0
    if addr.ip_address == "0.0.0.0"
      addr = Addrinfo.new(["AF_INET", addr.ip_port, nil, "127.0.0.1"], addr.pfamily, addr.socktype, addr.protocol)
    end
  elsif defined?(Socket::AF_INET6) && afamily == Socket::AF_INET6
    raise SocketError, "unbound IPv6 socket" if addr.ip_port == 0
    if addr.ip_address == "::"
      addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol)
    elsif addr.ip_address == "0.0.0.0" # MacOS X 10.4 returns "a.b.c.d" for IPv4-mapped IPv6 address.
      addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol)
    elsif addr.ip_address == "::ffff:0.0.0.0" # MacOS X 10.6 returns "::ffff:a.b.c.d" for IPv4-mapped IPv6 address.
      addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol)
    end
  elsif defined?(Socket::AF_UNIX) && afamily == Socket::AF_UNIX
    raise SocketError, "unbound Unix socket" if addr.unix_path == ""
  end
  addr
end
do_not_reverse_lookup → true or false click to toggle source

Gets the ::do_not_reverse_lookup flag of basicsocket.

TCPSocket.open("www.ruby-lang.org", 80) {|sock|
  p sock.do_not_reverse_lookup      #=> false
  p sock.peeraddr                   #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"]
  sock.do_not_reverse_lookup = true
  p sock.peeraddr                   #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"]
}

static VALUE
bsock_do_not_reverse_lookup(VALUE sock)
{
    rb_io_t *fptr;

    GetOpenFile(sock, fptr);
    return (fptr->mode & FMODE_NOREVLOOKUP) ? Qtrue : Qfalse;
}
do_not_reverse_lookup = bool click to toggle source

Sets the ::do_not_reverse_lookup flag of basicsocket.

BasicSocket.do_not_reverse_lookup = false
p TCPSocket.new("127.0.0.1", 80).do_not_reverse_lookup #=> false
BasicSocket.do_not_reverse_lookup = true
p TCPSocket.new("127.0.0.1", 80).do_not_reverse_lookup #=> true

static VALUE
bsock_do_not_reverse_lookup_set(VALUE sock, VALUE state)
{
    rb_io_t *fptr;

    rb_secure(4);
    GetOpenFile(sock, fptr);
    if (RTEST(state)) {
        fptr->mode |= FMODE_NOREVLOOKUP;
    }
    else {
        fptr->mode &= ~FMODE_NOREVLOOKUP;
    }
    return sock;
}
getpeereid → [euid, egid] click to toggle source

Returns the user and group on the peer of the UNIX socket. The result is a two element array which contains the effective uid and the effective gid.

Socket.unix_server_loop("/tmp/sock") {|s|
  begin
    euid, egid = s.getpeereid

    # Check the connected client is myself or not.
    next if euid != Process.uid

    # do something about my resource.

  ensure
    s.close
  end
}

static VALUE
bsock_getpeereid(VALUE self)
{
#if defined(HAVE_GETPEEREID)
    rb_io_t *fptr;
    uid_t euid;
    gid_t egid;
    GetOpenFile(self, fptr);
    if (getpeereid(fptr->fd, &euid, &egid) == -1)
        rb_sys_fail("getpeereid");
    return rb_assoc_new(UIDT2NUM(euid), GIDT2NUM(egid));
#elif defined(SO_PEERCRED) /* GNU/Linux */
    rb_io_t *fptr;
    struct ucred cred;
    socklen_t len = sizeof(cred);
    GetOpenFile(self, fptr);
    if (getsockopt(fptr->fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1)
        rb_sys_fail("getsockopt(SO_PEERCRED)");
    return rb_assoc_new(UIDT2NUM(cred.uid), GIDT2NUM(cred.gid));
#elif defined(HAVE_GETPEERUCRED) /* Solaris */
    rb_io_t *fptr;
    ucred_t *uc = NULL;
    VALUE ret;
    GetOpenFile(self, fptr);
    if (getpeerucred(fptr->fd, &uc) == -1)
        rb_sys_fail("getpeerucred");
    ret = rb_assoc_new(UIDT2NUM(ucred_geteuid(uc)), GIDT2NUM(ucred_getegid(uc)));
    ucred_free(uc);
    return ret;
#endif
}
getpeername → sockaddr click to toggle source

Returns the remote address of the socket as a sockaddr string.

TCPServer.open("127.0.0.1", 1440) {|serv|
  c = TCPSocket.new("127.0.0.1", 1440)
  s = serv.accept
  p s.getpeername #=> "\x02\x00\x82u\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
}

If Addrinfo object is preferred over the binary string, use #remote_address.

static VALUE
bsock_getpeername(VALUE sock)
{
    struct sockaddr_storage buf;
    socklen_t len = (socklen_t)sizeof buf;
    socklen_t len0 = len;
    rb_io_t *fptr;

    GetOpenFile(sock, fptr);
    if (getpeername(fptr->fd, (struct sockaddr*)&buf, &len) < 0)
        rb_sys_fail("getpeername(2)");
    if (len0 < len) len = len0;
    return rb_str_new((char*)&buf, len);
}
getsockname → sockaddr click to toggle source

Returns the local address of the socket as a sockaddr string.

TCPServer.open("127.0.0.1", 15120) {|serv|
  p serv.getsockname #=> "\x02\x00;\x10\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
}

If Addrinfo object is preferred over the binary string, use #local_address.

static VALUE
bsock_getsockname(VALUE sock)
{
    struct sockaddr_storage buf;
    socklen_t len = (socklen_t)sizeof buf;
    socklen_t len0 = len;
    rb_io_t *fptr;

    GetOpenFile(sock, fptr);
    if (getsockname(fptr->fd, (struct sockaddr*)&buf, &len) < 0)
        rb_sys_fail("getsockname(2)");
    if (len0 < len) len = len0;
    return rb_str_new((char*)&buf, len);
}
getsockopt(level, optname) → socketoption click to toggle source

Gets a socket option. These are protocol and system specific, see your local system documentation for details. The option is returned as a Socket::Option object.

Parameters

  • level is an integer, usually one of the SOL_ constants such as Socket::SOL_SOCKET, or a protocol level. A string or symbol of the name, possibly without prefix, is also accepted.

  • optname is an integer, usually one of the SO_ constants, such as Socket::SO_REUSEADDR. A string or symbol of the name, possibly without prefix, is also accepted.

Examples

Some socket options are integers with boolean values, in this case getsockopt could be called like this:

reuseaddr = sock.getsockopt(:SOCKET, :REUSEADDR).bool

optval = sock.getsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR)
optval = optval.unpack "i"
reuseaddr = optval[0] == 0 ? false : true

Some socket options are integers with numeric values, in this case getsockopt could be called like this:

ipttl = sock.getsockopt(:IP, :TTL).int

optval = sock.getsockopt(Socket::IPPROTO_IP, Socket::IP_TTL)
ipttl = optval.unpack("i")[0]

Option values may be structs. Decoding them can be complex as it involves examining your system headers to determine the correct definition. An example is a +struct linger+, which may be defined in your system headers as:

struct linger {
  int l_onoff;
  int l_linger;
};

In this case getsockopt could be called like this:

# Socket::Option knows linger structure.
onoff, linger = sock.getsockopt(:SOCKET, :LINGER).linger

optval =  sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER)
onoff, linger = optval.unpack "ii"
onoff = onoff == 0 ? false : true
static VALUE
bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname)
{
    int level, option;
    socklen_t len;
    char *buf;
    rb_io_t *fptr;
    int family;

    GetOpenFile(sock, fptr);
    family = rsock_getfamily(fptr->fd);
    level = rsock_level_arg(family, lev);
    option = rsock_optname_arg(family, level, optname);
    len = 256;
    buf = ALLOCA_N(char,len);

    rb_io_check_closed(fptr);

    if (getsockopt(fptr->fd, level, option, buf, &len) < 0)
        rb_sys_fail_path(fptr->pathv);

    return rsock_sockopt_new(family, level, option, rb_str_new(buf, len));
}
local_address → addrinfo click to toggle source

Returns an Addrinfo object for local address obtained by getsockname.

Note that addrinfo.protocol is filled by 0.

TCPSocket.open("www.ruby-lang.org", 80) {|s|
  p s.local_address #=> #<Addrinfo: 192.168.0.129:36873 TCP>
}

TCPServer.open("127.0.0.1", 1512) {|serv|
  p serv.local_address #=> #<Addrinfo: 127.0.0.1:1512 TCP>
}

static VALUE
bsock_local_address(VALUE sock)
{
    struct sockaddr_storage buf;
    socklen_t len = (socklen_t)sizeof buf;
    socklen_t len0 = len;
    rb_io_t *fptr;

    GetOpenFile(sock, fptr);
    if (getsockname(fptr->fd, (struct sockaddr*)&buf, &len) < 0)
        rb_sys_fail("getsockname(2)");
    if (len0 < len) len = len0;
    return rsock_fd_socket_addrinfo(fptr->fd, (struct sockaddr *)&buf, len);
}
recv(maxlen) → mesg click to toggle source
recv(maxlen, flags) → mesg

Receives a message.

maxlen is the maximum number of bytes to receive.

flags should be a bitwise OR of Socket::MSG_* constants.

UNIXSocket.pair {|s1, s2|
  s1.puts "Hello World"
  p s2.recv(4)                     #=> "Hell"
  p s2.recv(4, Socket::MSG_PEEK)   #=> "o Wo"
  p s2.recv(4)                     #=> "o Wo"
  p s2.recv(10)                    #=> "rld\n"
}

static VALUE
bsock_recv(int argc, VALUE *argv, VALUE sock)
{
    return rsock_s_recvfrom(sock, argc, argv, RECV_RECV);
}
recv_nonblock(maxlen) → mesg click to toggle source
recv_nonblock(maxlen, flags) → mesg

Receives up to maxlen bytes from socket using recvfrom(2) after O_NONBLOCK is set for the underlying file descriptor. flags is zero or more of the MSG_ options. The result, mesg, is the data received.

When recvfrom(2) returns 0, #recv_nonblock returns an empty string as data. The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.

Parameters

  • maxlen - the number of bytes to receive from the socket

  • flags - zero or more of the MSG_ options

Example

serv = TCPServer.new("127.0.0.1", 0)
af, port, host, addr = serv.addr
c = TCPSocket.new(addr, port)
s = serv.accept
c.send "aaa", 0
begin # emulate blocking recv.
  p s.recv_nonblock(10) #=> "aaa"
rescue IO::WaitReadable
  IO.select([s])
  retry
end

Refer to Socket#recvfrom for the exceptions that may be thrown if the call to #recv_nonblock fails.

#recv_nonblock may raise any error corresponding to recvfrom(2) failure, including Errno::EWOULDBLOCK.

If the exception is Errno::EWOULDBLOCK or Errno::AGAIN, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying recv_nonblock.

See

  • Socket#recvfrom

static VALUE
bsock_recv_nonblock(int argc, VALUE *argv, VALUE sock)
{
    return rsock_s_recvfrom_nonblock(sock, argc, argv, RECV_RECV);
}
recvmsg(maxmesglen=nil, flags=0, maxcontrollen=nil, opts={}) → [mesg, sender_addrinfo, rflags, *controls] click to toggle source

recvmsg receives a message using recvmsg(2) system call in blocking manner.

maxmesglen is the maximum length of mesg to receive.

flags is bitwise OR of MSG_* constants such as Socket::MSG_PEEK.

maxcontrollen is the maximum length of controls (ancillary data) to receive.

opts is option hash. Currently :scm_rights=>bool is the only option.

:scm_rights option specifies that application expects SCM_RIGHTS control message. If the value is nil or false, application don't expects SCM_RIGHTS control message. In this case, recvmsg closes the passed file descriptors immediately. This is the default behavior.

If :scm_rights value is neither nil nor false, application expects SCM_RIGHTS control message. In this case, recvmsg creates IO objects for each file descriptors for Socket::AncillaryData#unix_rights method.

The return value is 4-elements array.

mesg is a string of the received message.

sender_addrinfo is a sender socket address for connection-less socket. It is an Addrinfo object. For connection-oriented socket such as TCP, sender_addrinfo is platform dependent.

rflags is a flags on the received message which is bitwise OR of MSG_* constants such as Socket::MSG_TRUNC. It will be nil if the system uses 4.3BSD style old recvmsg system call.

controls is ancillary data which is an array of Socket::AncillaryData objects such as:

#<Socket::AncillaryData: AF_UNIX SOCKET RIGHTS 7>

maxmesglen and maxcontrollen can be nil. In that case, the buffer will be grown until the message is not truncated. Internally, MSG_PEEK is used and MSG_TRUNC/MSG_CTRUNC are checked.

recvmsg can be used to implement recv_io as follows:

mesg, sender_sockaddr, rflags, *controls = sock.recvmsg(:scm_rights=>true)
controls.each {|ancdata|
  if ancdata.cmsg_is?(:SOCKET, :RIGHTS)
    return ancdata.unix_rights[0]
  end
}

VALUE
rsock_bsock_recvmsg(int argc, VALUE *argv, VALUE sock)
{
    return bsock_recvmsg_internal(argc, argv, sock, 0);
}
recvmsg_nonblock(maxdatalen=nil, flags=0, maxcontrollen=nil, opts={}) → [data, sender_addrinfo, rflags, *controls] click to toggle source

recvmsg receives a message using recvmsg(2) system call in non-blocking manner.

It is similar to #recvmsg but non-blocking flag is set before the system call and it doesn't retry the system call.

VALUE
rsock_bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock)
{
    return bsock_recvmsg_internal(argc, argv, sock, 1);
}
remote_address → addrinfo click to toggle source

Returns an Addrinfo object for remote address obtained by getpeername.

Note that addrinfo.protocol is filled by 0.

TCPSocket.open("www.ruby-lang.org", 80) {|s|
  p s.remote_address #=> #<Addrinfo: 221.186.184.68:80 TCP>
}

TCPServer.open("127.0.0.1", 1728) {|serv|
  c = TCPSocket.new("127.0.0.1", 1728)
  s = serv.accept
  p s.remote_address #=> #<Addrinfo: 127.0.0.1:36504 TCP>
}

static VALUE
bsock_remote_address(VALUE sock)
{
    struct sockaddr_storage buf;
    socklen_t len = (socklen_t)sizeof buf;
    socklen_t len0 = len;
    rb_io_t *fptr;

    GetOpenFile(sock, fptr);
    if (getpeername(fptr->fd, (struct sockaddr*)&buf, &len) < 0)
        rb_sys_fail("getpeername(2)");
    if (len0 < len) len = len0;
    return rsock_fd_socket_addrinfo(fptr->fd, (struct sockaddr *)&buf, len);
}
send(mesg, flags [, dest_sockaddr]) → numbytes_sent click to toggle source

send mesg via basicsocket.

mesg should be a string.

flags should be a bitwise OR of Socket::MSG_* constants.

dest_sockaddr should be a packed sockaddr string or an addrinfo.

TCPSocket.open("localhost", 80) {|s|
  s.send "GET / HTTP/1.0\r\n\r\n", 0
  p s.read
}

VALUE
rsock_bsock_send(int argc, VALUE *argv, VALUE sock)
{
    struct rsock_send_arg arg;
    VALUE flags, to;
    rb_io_t *fptr;
    int n;
    rb_blocking_function_t *func;

    rb_secure(4);
    rb_scan_args(argc, argv, "21", &arg.mesg, &flags, &to);

    StringValue(arg.mesg);
    if (!NIL_P(to)) {
        SockAddrStringValue(to);
        to = rb_str_new4(to);
        arg.to = (struct sockaddr *)RSTRING_PTR(to);
        arg.tolen = (socklen_t)RSTRING_LENINT(to);
        func = rsock_sendto_blocking;
    }
    else {
        func = rsock_send_blocking;
    }
    GetOpenFile(sock, fptr);
    arg.fd = fptr->fd;
    arg.flags = NUM2INT(flags);
    while (rb_thread_fd_writable(arg.fd),
           (n = (int)BLOCKING_REGION_FD(func, &arg)) < 0) {
        if (rb_io_wait_writable(arg.fd)) {
            continue;
        }
        rb_sys_fail("send(2)");
    }
    return INT2FIX(n);
}
sendmsg(mesg, flags=0, dest_sockaddr=nil, *controls) → numbytes_sent click to toggle source

sendmsg sends a message using sendmsg(2) system call in blocking manner.

mesg is a string to send.

flags is bitwise OR of MSG_* constants such as Socket::MSG_OOB.

dest_sockaddr is a destination socket address for connection-less socket. It should be a sockaddr such as a result of Socket.sockaddr_in. An Addrinfo object can be used too.

controls is a list of ancillary data. The element of controls should be Socket::AncillaryData or 3-elements array. The 3-element array should contains cmsg_level, cmsg_type and data.

The return value, numbytes_sent is an integer which is the number of bytes sent.

sendmsg can be used to implement send_io as follows:

# use Socket::AncillaryData.
ancdata = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, io.fileno)
sock.sendmsg("a", 0, nil, ancdata)

# use 3-element array.
ancdata = [:SOCKET, :RIGHTS, [io.fileno].pack("i!")]
sock.sendmsg("\0", 0, nil, ancdata)
VALUE
rsock_bsock_sendmsg(int argc, VALUE *argv, VALUE sock)
{
    return bsock_sendmsg_internal(argc, argv, sock, 0);
}
sendmsg_nonblock(mesg, flags=0, dest_sockaddr=nil, *controls) → numbytes_sent click to toggle source

#sendmsg_nonblock sends a message using sendmsg(2) system call in non-blocking manner.

It is similar to #sendmsg but the non-blocking flag is set before the system call and it doesn't retry the system call.

VALUE
rsock_bsock_sendmsg_nonblock(int argc, VALUE *argv, VALUE sock)
{
    return bsock_sendmsg_internal(argc, argv, sock, 1);
}
setsockopt(level, optname, optval) click to toggle source
setsockopt(socketoption)

Sets a socket option. These are protocol and system specific, see your local system documentation for details.

Parameters

  • level is an integer, usually one of the SOL_ constants such as Socket::SOL_SOCKET, or a protocol level. A string or symbol of the name, possibly without prefix, is also accepted.

  • optname is an integer, usually one of the SO_ constants, such as Socket::SO_REUSEADDR. A string or symbol of the name, possibly without prefix, is also accepted.

  • optval is the value of the option, it is passed to the underlying setsockopt() as a pointer to a certain number of bytes. How this is done depends on the type:

    • Fixnum: value is assigned to an int, and a pointer to the int is passed, with length of sizeof(int).

    • true or false: 1 or 0 (respectively) is assigned to an int, and the int is passed as for a Fixnum. Note that false must be passed, not nil.

    • String: the string's data and length is passed to the socket.

  • socketoption is an instance of Socket::Option

Examples

Some socket options are integers with boolean values, in this case setsockopt could be called like this:

sock.setsockopt(:SOCKET, :REUSEADDR, true)
sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
sock.setsockopt(Socket::Option.bool(:INET, :SOCKET, :REUSEADDR, true))

Some socket options are integers with numeric values, in this case setsockopt could be called like this:

sock.setsockopt(:IP, :TTL, 255)
sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, 255)
sock.setsockopt(Socket::Option.int(:INET, :IP, :TTL, 255))

Option values may be structs. Passing them can be complex as it involves examining your system headers to determine the correct definition. An example is an ip_mreq, which may be defined in your system headers as:

struct ip_mreq {
  struct  in_addr imr_multiaddr;
  struct  in_addr imr_interface;
};

In this case setsockopt could be called like this:

optval = IPAddr.new("224.0.0.251").hton +
         IPAddr.new(Socket::INADDR_ANY, Socket::AF_INET).hton
sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval)
static VALUE
bsock_setsockopt(int argc, VALUE *argv, VALUE sock)
{
    VALUE lev, optname, val;
    int family, level, option;
    rb_io_t *fptr;
    int i;
    char *v;
    int vlen;

    if (argc == 1) {
        lev = rb_funcall(argv[0], rb_intern("level"), 0);
        optname = rb_funcall(argv[0], rb_intern("optname"), 0);
        val = rb_funcall(argv[0], rb_intern("data"), 0);
    }
    else {
        rb_scan_args(argc, argv, "30", &lev, &optname, &val);
    }

    rb_secure(2);
    GetOpenFile(sock, fptr);
    family = rsock_getfamily(fptr->fd);
    level = rsock_level_arg(family, lev);
    option = rsock_optname_arg(family, level, optname);

    switch (TYPE(val)) {
      case T_FIXNUM:
        i = FIX2INT(val);
        goto numval;
      case T_FALSE:
        i = 0;
        goto numval;
      case T_TRUE:
        i = 1;
      numval:
        v = (char*)&i; vlen = (int)sizeof(i);
        break;
      default:
        StringValue(val);
        v = RSTRING_PTR(val);
        vlen = RSTRING_LENINT(val);
        break;
    }

#define rb_sys_fail_path(path) rb_sys_fail_str(path)

    rb_io_check_closed(fptr);
    if (setsockopt(fptr->fd, level, option, v, vlen) < 0)
        rb_sys_fail_path(fptr->pathv);

    return INT2FIX(0);
}
shutdown([how]) → 0 click to toggle source

Calls shutdown(2) system call.

s.shutdown(Socket::SHUT_RD) disallows further read.

s.shutdown(Socket::SHUT_WR) disallows further write.

s.shutdown(Socket::SHUT_RDWR) disallows further read and write.

how can be symbol or string:

  • :RD, :SHUT_RD, “RD” and “SHUT_RD” are accepted as Socket::SHUT_RD.

  • :WR, :SHUT_WR, “WR” and “SHUT_WR” are accepted as Socket::SHUT_WR.

  • :RDWR, :SHUT_RDWR, “RDWR” and “SHUT_RDWR” are accepted as Socket::SHUT_RDWR.

    UNIXSocket.pair {|s1, s2|

    s1.puts "ping"
s1.shutdown(:WR)
p s2.read          #=> "ping\n"
s2.puts "pong"
s2.close
p s1.read          #=> "pong\n"

    }

static VALUE
bsock_shutdown(int argc, VALUE *argv, VALUE sock)
{
    VALUE howto;
    int how;
    rb_io_t *fptr;

    if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
        rb_raise(rb_eSecurityError, "Insecure: can't shutdown socket");
    }
    rb_scan_args(argc, argv, "01", &howto);
    if (howto == Qnil)
        how = SHUT_RDWR;
    else {
        how = rsock_shutdown_how_arg(howto);
        if (how != SHUT_WR && how != SHUT_RD && how != SHUT_RDWR) {
            rb_raise(rb_eArgError, "`how' should be either :SHUT_RD, :SHUT_WR, :SHUT_RDWR");
        }
    }
    GetOpenFile(sock, fptr);
    if (shutdown(fptr->fd, how) == -1)
        rb_sys_fail(0);

    return INT2FIX(0);
}


module Benchmark - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Benchmark

The Benchmark module provides methods to measure and report the time used to execute Ruby code.

  • Measure the time to construct the string given by the expression "a"*1_000_000:

    require 'benchmark'

puts Benchmark.measure { "a"*1_000_000 }

    On my machine (FreeBSD 3.2 on P5, 100MHz) this generates:

    1.166667   0.050000   1.216667 (  0.571355)

    This report shows the user CPU time, system CPU time, the sum of the user and system CPU times, and the elapsed real time. The unit of time is seconds.

  • Do some experiments sequentially using the bm method:

    require 'benchmark'

n = 50000
Benchmark.bm do |x|
  x.report { for i in 1..n; a = "1"; end }
  x.report { n.times do   ; a = "1"; end }
  x.report { 1.upto(n) do ; a = "1"; end }
end

    The result:

        user     system      total        real
1.033333   0.016667   1.016667 (  0.492106)
1.483333   0.000000   1.483333 (  0.694605)
1.516667   0.000000   1.516667 (  0.711077)

  • Continuing the previous example, put a label in each report:

    require 'benchmark'

n = 50000
Benchmark.bm(7) do |x|
  x.report("for:")   { for i in 1..n; a = "1"; end }
  x.report("times:") { n.times do   ; a = "1"; end }
  x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
end

The result:

             user     system      total        real
for:     1.050000   0.000000   1.050000 (  0.503462)
times:   1.533333   0.016667   1.550000 (  0.735473)
upto:    1.500000   0.016667   1.516667 (  0.711239)

  • The times for some benchmarks depend on the order in which items are run. These differences are due to the cost of memory allocation and garbage collection. To avoid these discrepancies, the bmbm method is provided. For example, to compare ways to sort an array of floats:

    require 'benchmark'

array = (1..1000000).map { rand }

Benchmark.bmbm do |x|
  x.report("sort!") { array.dup.sort! }
  x.report("sort")  { array.dup.sort  }
end

    The result:

    Rehearsal -----------------------------------------
sort!  11.928000   0.010000  11.938000 ( 12.756000)
sort   13.048000   0.020000  13.068000 ( 13.857000)
------------------------------- total: 25.006000sec

            user     system      total        real
sort!  12.959000   0.010000  12.969000 ( 13.793000)
sort   12.007000   0.000000  12.007000 ( 12.791000)

  • Report statistics of sequential experiments with unique labels, using the benchmark method:

    require 'benchmark'
include Benchmark         # we need the CAPTION and FORMAT constants

n = 50000
Benchmark.benchmark(CAPTION, 7, FORMAT, ">total:", ">avg:") do |x|
  tf = x.report("for:")   { for i in 1..n; a = "1"; end }
  tt = x.report("times:") { n.times do   ; a = "1"; end }
  tu = x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
  [tf+tt+tu, (tf+tt+tu)/3]
end

    The result:

                 user     system      total        real
for:     1.016667   0.016667   1.033333 (  0.485749)
times:   1.450000   0.016667   1.466667 (  0.681367)
upto:    1.533333   0.000000   1.533333 (  0.722166)
>total:  4.000000   0.033333   4.033333 (  1.889282)
>avg:    1.333333   0.011111   1.344444 (  0.629761)

In Files

  • lib/benchmark.rb

Constants

CAPTION

The default caption string (heading above the output times).

FORMAT

The default format string used to display times. See also Benchmark::Tms#format.

Public Class Methods

benchmark(caption = "", label_width = nil, format = nil, *labels) { |report| ... } click to toggle source

Invokes the block with a Benchmark::Report object, which may be used to collect and report on the results of individual benchmark tests. Reserves label_width leading spaces for labels on each line. Prints caption at the top of the report, and uses format to format each line. Returns an array of Benchmark::Tms objects.

If the block returns an array of Benchmark::Tms objects, these will be used to format additional lines of output. If label parameters are given, these are used to label these extra lines.

Note: Other methods provide a simpler interface to this one, and are suitable for nearly all benchmarking requirements. See the examples in Benchmark, and the bm and bmbm methods.

Example:

require 'benchmark'
include Benchmark          # we need the CAPTION and FORMAT constants

n = 50000
Benchmark.benchmark(CAPTION, 7, FORMAT, ">total:", ">avg:") do |x|
  tf = x.report("for:")   { for i in 1..n; a = "1"; end }
  tt = x.report("times:") { n.times do   ; a = "1"; end }
  tu = x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
  [tf+tt+tu, (tf+tt+tu)/3]
end

Generates:

             user     system      total        real
for:     1.016667   0.016667   1.033333 (  0.485749)
times:   1.450000   0.016667   1.466667 (  0.681367)
upto:    1.533333   0.000000   1.533333 (  0.722166)
>total:  4.000000   0.033333   4.033333 (  1.889282)
>avg:    1.333333   0.011111   1.344444 (  0.629761)
# File lib/benchmark.rb, line 166
def benchmark(caption = "", label_width = nil, format = nil, *labels) # :yield: report
  sync = STDOUT.sync
  STDOUT.sync = true
  label_width ||= 0
  label_width += 1
  format ||= FORMAT
  print ' '*label_width + caption unless caption.empty?
  report = Report.new(label_width, format)
  results = yield(report)
  Array === results and results.grep(Tms).each {|t|
    print((labels.shift || t.label || "").ljust(label_width), t.format(format))
  }
  report.list
ensure
  STDOUT.sync = sync unless sync.nil?
end
bm(label_width = 0, *labels) { |report| ... } click to toggle source

A simple interface to the benchmark method, bm is generates sequential reports with labels. The parameters have the same meaning as for benchmark.

require 'benchmark'

n = 50000
Benchmark.bm(7) do |x|
  x.report("for:")   { for i in 1..n; a = "1"; end }
  x.report("times:") { n.times do   ; a = "1"; end }
  x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
end

Generates:

             user     system      total        real
for:     1.050000   0.000000   1.050000 (  0.503462)
times:   1.533333   0.016667   1.550000 (  0.735473)
upto:    1.500000   0.016667   1.516667 (  0.711239)
# File lib/benchmark.rb, line 205
def bm(label_width = 0, *labels, &blk) # :yield: report
  benchmark(CAPTION, label_width, FORMAT, *labels, &blk)
end
bmbm(width = 0) { |job| ... } click to toggle source

Sometimes benchmark results are skewed because code executed earlier encounters different garbage collection overheads than that run later. bmbm attempts to minimize this effect by running the tests twice, the first time as a rehearsal in order to get the runtime environment stable, the second time for real. GC.start is executed before the start of each of the real timings; the cost of this is not included in the timings. In reality, though, there's only so much that bmbm can do, and the results are not guaranteed to be isolated from garbage collection and other effects.

Because bmbm takes two passes through the tests, it can calculate the required label width.

require 'benchmark'

array = (1..1000000).map { rand }

Benchmark.bmbm do |x|
  x.report("sort!") { array.dup.sort! }
  x.report("sort")  { array.dup.sort  }
end

Generates:

Rehearsal -----------------------------------------
sort!  11.928000   0.010000  11.938000 ( 12.756000)
sort   13.048000   0.020000  13.068000 ( 13.857000)
------------------------------- total: 25.006000sec

            user     system      total        real
sort!  12.959000   0.010000  12.969000 ( 13.793000)
sort   12.007000   0.000000  12.007000 ( 12.791000)

bmbm yields a Benchmark::Job object and returns an array of Benchmark::Tms objects.

# File lib/benchmark.rb, line 247
def bmbm(width = 0) # :yield: job
  job = Job.new(width)
  yield(job)
  width = job.width + 1
  sync = STDOUT.sync
  STDOUT.sync = true

  # rehearsal
  puts 'Rehearsal '.ljust(width+CAPTION.length,'-')
  ets = job.list.inject(Tms.new) { |sum,(label,item)|
    print label.ljust(width)
    res = Benchmark.measure(&item)
    print res.format
    sum + res
  }.format("total: %tsec")
  print " #{ets}\n\n".rjust(width+CAPTION.length+2,'-')

  # take
  print ' '*width + CAPTION
  job.list.map { |label,item|
    GC.start
    print label.ljust(width)
    Benchmark.measure(label, &item).tap { |res| print res }
  }
ensure
  STDOUT.sync = sync unless sync.nil?
end
measure(label = "") { || ... } click to toggle source

Returns the time used to execute the given block as a Benchmark::Tms object.

# File lib/benchmark.rb, line 279
def measure(label = "") # :yield:
  t0, r0 = Process.times, Time.now
  yield
  t1, r1 = Process.times, Time.now
  Benchmark::Tms.new(t1.utime  - t0.utime,
                     t1.stime  - t0.stime,
                     t1.cutime - t0.cutime,
                     t1.cstime - t0.cstime,
                     r1 - r0,
                     label)
end
realtime() { || ... } click to toggle source

Returns the elapsed real time used to execute the given block.

# File lib/benchmark.rb, line 294
def realtime # :yield:
  r0 = Time.now
  yield
  Time.now - r0
end


class Benchmark::Tms - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Benchmark::Tms

A data object, representing the times associated with a benchmark measurement.

In Files

  • lib/benchmark.rb

Parent

Object

Constants

CAPTION

Default caption, see also Benchmark::CAPTION

FORMAT

Default format string, see also Benchmark::FORMAT

Attributes

cstime[R]

System CPU time of children

cutime[R]

User CPU time of children

label[R]

Label

real[R]

Elapsed real time

stime[R]

System CPU time

total[R]

Total time, that is utime + stime + cutime + cstime

utime[R]

User CPU time

Public Class Methods

new(utime = 0.0, stime = 0.0, cutime = 0.0, cstime = 0.0, real = 0.0, label = nil) click to toggle source

Returns an initialized Tms object which has utime as the user CPU time, stime as the system CPU time, cutime as the children's user CPU time, cstime as the children's system CPU time, real as the elapsed real time and label as the label.

# File lib/benchmark.rb, line 415
def initialize(utime = 0.0, stime = 0.0, cutime = 0.0, cstime = 0.0, real = 0.0, label = nil)
  @utime, @stime, @cutime, @cstime, @real, @label = utime, stime, cutime, cstime, real, label.to_s
  @total = @utime + @stime + @cutime + @cstime
end

Public Instance Methods

*(x) click to toggle source

Returns a new Tms object obtained by memberwise multiplication of the individual times for this Tms object by x.

# File lib/benchmark.rb, line 460
def *(x); memberwise(:*, x) end
+(other) click to toggle source

Returns a new Tms object obtained by memberwise summation of the individual times for this Tms object with those of the other Tms object. This method and #/() are useful for taking statistics.

# File lib/benchmark.rb, line 447
def +(other); memberwise(:+, other) end
-(other) click to toggle source

Returns a new Tms object obtained by memberwise subtraction of the individual times for the other Tms object from those of this Tms object.

# File lib/benchmark.rb, line 454
def -(other); memberwise(:-, other) end
/(x) click to toggle source

Returns a new Tms object obtained by memberwise division of the individual times for this Tms object by x. This method and #+() are useful for taking statistics.

# File lib/benchmark.rb, line 467
def /(x); memberwise(:/, x) end
add() { || ... } click to toggle source

Returns a new Tms object whose times are the sum of the times for this Tms object, plus the time required to execute the code block (blk).

# File lib/benchmark.rb, line 424
def add(&blk) # :yield:
  self + Benchmark.measure(&blk)
end
add!(&blk) click to toggle source

An in-place version of add.

# File lib/benchmark.rb, line 431
def add!(&blk)
  t = Benchmark.measure(&blk)
  @utime  = utime + t.utime
  @stime  = stime + t.stime
  @cutime = cutime + t.cutime
  @cstime = cstime + t.cstime
  @real   = real + t.real
  self
end
format(format = nil, *args) click to toggle source

Returns the contents of this Tms object as a formatted string, according to a format string like that passed to Kernel.format. In addition, format accepts the following extensions:

%u

Replaced by the user CPU time, as reported by #utime.

%y

Replaced by the system CPU time, as reported by stime (Mnemonic: y of “s*y*stem”)

%U

Replaced by the children's user CPU time, as reported by #cutime

%Y

Replaced by the children's system CPU time, as reported by #cstime

%t

Replaced by the total CPU time, as reported by #total

%r

Replaced by the elapsed real time, as reported by #real

%n

Replaced by the label string, as reported by #label (Mnemonic: n of “*n*ame”)

If format is not given, FORMAT is used as default value, detailing the user, system and real elapsed time.

# File lib/benchmark.rb, line 486
def format(format = nil, *args)
  str = (format || FORMAT).dup
  str.gsub!(/(%[-+.\d]*)n/) { "#{$1}s" % label }
  str.gsub!(/(%[-+.\d]*)u/) { "#{$1}f" % utime }
  str.gsub!(/(%[-+.\d]*)y/) { "#{$1}f" % stime }
  str.gsub!(/(%[-+.\d]*)U/) { "#{$1}f" % cutime }
  str.gsub!(/(%[-+.\d]*)Y/) { "#{$1}f" % cstime }
  str.gsub!(/(%[-+.\d]*)t/) { "#{$1}f" % total }
  str.gsub!(/(%[-+.\d]*)r/) { "(#{$1}f)" % real }
  format ? str % args : str
end
to_a() click to toggle source

Returns a new 6-element array, consisting of the label, user CPU time, system CPU time, children's user CPU time, children's system CPU time and elapsed real time.

# File lib/benchmark.rb, line 511
def to_a
  [@label, @utime, @stime, @cutime, @cstime, @real]
end
to_s() click to toggle source

Same as format.

# File lib/benchmark.rb, line 501
def to_s
  format
end

Protected Instance Methods

memberwise(op, x) click to toggle source

Returns a new Tms object obtained by memberwise operation op of the individual times for this Tms object with those of the other Tms object.

op can be a mathematical operation such as +, -, *, /

# File lib/benchmark.rb, line 525
def memberwise(op, x)
  case x
  when Benchmark::Tms
    Benchmark::Tms.new(utime.__send__(op, x.utime),
                       stime.__send__(op, x.stime),
                       cutime.__send__(op, x.cutime),
                       cstime.__send__(op, x.cstime),
                       real.__send__(op, x.real)
                       )
  else
    Benchmark::Tms.new(utime.__send__(op, x),
                       stime.__send__(op, x),
                       cutime.__send__(op, x),
                       cstime.__send__(op, x),
                       real.__send__(op, x)
                       )
  end
end


class BigDecimal - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class BigDecimal

BigDecimal provides arbitrary-precision floating point decimal arithmetic.

Copyright (C) 2002 by Shigeo Kobayashi <shigeo@tinyforest.gr.jp>.

You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the README file of the BigDecimal distribution.

Documented by mathew <meta@pobox.com>.

Introduction

Ruby provides built-in support for arbitrary precision integer arithmetic.

For example:

42**13  #=>   1265437718438866624512

BigDecimal provides similar support for very large or very accurate floating point numbers.

Decimal arithmetic is also useful for general calculation, because it provides the correct answers people expect–whereas normal binary floating point arithmetic often introduces subtle errors because of the conversion between base 10 and base 2.

For example, try:

sum = 0
for i in (1..10000)
  sum = sum + 0.0001
end
print sum #=> 0.9999999999999062

and contrast with the output from:

require 'bigdecimal'

sum = BigDecimal.new("0")
for i in (1..10000)
  sum = sum + BigDecimal.new("0.0001")
end
print sum #=> 0.1E1

Similarly:

(BigDecimal.new("1.2") - BigDecimal("1.0")) == BigDecimal("0.2") #=> true

(1.2 - 1.0) == 0.2 #=> false

Special features of accurate decimal arithmetic

Because BigDecimal is more accurate than normal binary floating point arithmetic, it requires some special values.

Infinity

BigDecimal sometimes needs to return infinity, for example if you divide a value by zero.

BigDecimal.new("1.0") / BigDecimal.new("0.0")  #=> infinity
BigDecimal.new("-1.0") / BigDecimal.new("0.0")  #=> -infinity

You can represent infinite numbers to BigDecimal using the strings 'Infinity', '+Infinity' and '-Infinity' (case-sensitive)

Not a Number

When a computation results in an undefined value, the special value NaN (for 'not a number') is returned.

Example:

BigDecimal.new("0.0") / BigDecimal.new("0.0") #=> NaN

You can also create undefined values.

NaN is never considered to be the same as any other value, even NaN itself:

n = BigDecimal.new('NaN')
n == 0.0 #=> nil
n == n #=> nil

Positive and negative zero

If a computation results in a value which is too small to be represented as a BigDecimal within the currently specified limits of precision, zero must be returned.

If the value which is too small to be represented is negative, a BigDecimal value of negative zero is returned.

BigDecimal.new("1.0") / BigDecimal.new("-Infinity") #=> -0.0

If the value is positive, a value of positive zero is returned.

BigDecimal.new("1.0") / BigDecimal.new("Infinity") #=> 0.0

(See ::mode for how to specify limits of precision.)

Note that -0.0 and 0.0 are considered to be the same for the purposes of comparison.

Note also that in mathematics, there is no particular concept of negative or positive zero; true mathematical zero has no sign.

In Files

  • ext/bigdecimal/bigdecimal.c
  • ext/bigdecimal/lib/bigdecimal/util.rb
  • ext/json/lib/json/add/bigdecimal.rb

Parent

Numeric

Constants

BASE

Base value used in internal calculations. On a 32 bit system, BASE is 10000, indicating that calculation is done in groups of 4 digits. (If it were larger, BASE**2 wouldn't fit in 32 bits, so you couldn't guarantee that two groups could always be multiplied together without overflow.)

EXCEPTION_ALL

Determines whether overflow, underflow or zero divide result in an exception being thrown. See ::mode.

EXCEPTION_INFINITY

Determines what happens when the result of a computation is infinity. See ::mode.

EXCEPTION_NaN

Determines what happens when the result of a computation is not a number (NaN). See ::mode.

EXCEPTION_OVERFLOW

Determines what happens when the result of a computation is an overflow (a result too large to be represented). See ::mode.

EXCEPTION_UNDERFLOW

Determines what happens when the result of a computation is an underflow (a result too small to be represented). See ::mode.

EXCEPTION_ZERODIVIDE

Determines what happens when a division by zero is performed. See ::mode.

INFINITY

Positive infinity value.

NAN

'Not a Number' value.

ROUND_CEILING

Round towards +infinity. See ::mode.

ROUND_DOWN

Indicates that values should be rounded towards zero. See ::mode.

ROUND_FLOOR

Round towards -infinity. See ::mode.

ROUND_HALF_DOWN

Indicates that digits >= 6 should be rounded up, others rounded down. See ::mode.

ROUND_HALF_EVEN

Round towards the even neighbor. See ::mode.

ROUND_HALF_UP

Indicates that digits >= 5 should be rounded up, others rounded down. See ::mode.

ROUND_MODE

Determines what happens when a result must be rounded in order to fit in the appropriate number of significant digits. See ::mode.

ROUND_UP

Indicates that values should be rounded away from zero. See ::mode.

SIGN_NEGATIVE_FINITE

Indicates that a value is negative and finite. See #sign.

SIGN_NEGATIVE_INFINITE

Indicates that a value is negative and infinite. See #sign.

SIGN_NEGATIVE_ZERO

Indicates that a value is -0. See #sign.

SIGN_NaN

Indicates that a value is not a number. See #sign.

SIGN_POSITIVE_FINITE

Indicates that a value is positive and finite. See #sign.

SIGN_POSITIVE_INFINITE

Indicates that a value is positive and infinite. See #sign.

SIGN_POSITIVE_ZERO

Indicates that a value is +0. See #sign.

Public Class Methods

_load(p1) click to toggle source

Internal method used to provide marshalling support. See the Marshal module.

static VALUE
BigDecimal_load(VALUE self, VALUE str)
{
    ENTER(2);
    Real *pv;
    unsigned char *pch;
    unsigned char ch;
    unsigned long m=0;

    SafeStringValue(str);
    pch = (unsigned char *)RSTRING_PTR(str);
    /* First get max prec */
    while((*pch)!=(unsigned char)'\0' && (ch=*pch++)!=(unsigned char)':') {
        if(!ISDIGIT(ch)) {
            rb_raise(rb_eTypeError, "load failed: invalid character in the marshaled string");
        }
        m = m*10 + (unsigned long)(ch-'0');
    }
    if(m>VpBaseFig()) m -= VpBaseFig();
    GUARD_OBJ(pv,VpNewRbClass(m,(char *)pch,self));
    m /= VpBaseFig();
    if(m && pv->MaxPrec>m) pv->MaxPrec = m+1;
    return ToValue(pv);
}
double_fig click to toggle source

The ::double_fig class method returns the number of digits a Float number is allowed to have. The result depends upon the CPU and OS in use.

static VALUE
BigDecimal_double_fig(VALUE self)
{
    return INT2FIX(VpDblFig());
}
json_create(object) click to toggle source

Import a JSON Marshalled object.

method used for JSON marshalling support.

# File ext/json/lib/json/add/bigdecimal.rb, line 10
def self.json_create(object)
  BigDecimal._load object['b']
end
limit(digits) click to toggle source

Limit the number of significant digits in newly created BigDecimal numbers to the specified value. Rounding is performed as necessary, as specified by ::mode.

A limit of 0, the default, means no upper limit.

The limit specified by this method takes less priority over any limit specified to instance methods such as ceil, floor, truncate, or round.

static VALUE
BigDecimal_limit(int argc, VALUE *argv, VALUE self)
{
    VALUE  nFig;
    VALUE  nCur = INT2NUM(VpGetPrecLimit());

    if(rb_scan_args(argc,argv,"01",&nFig)==1) {
        int nf;
        if(nFig==Qnil) return nCur;
        Check_Type(nFig, T_FIXNUM);
        nf = FIX2INT(nFig);
        if(nf<0) {
            rb_raise(rb_eArgError, "argument must be positive");
        }
        VpSetPrecLimit(nf);
    }
    return nCur;
}
mode(mode, value) click to toggle source

Controls handling of arithmetic exceptions and rounding. If no value is supplied, the current value is returned.

Six values of the mode parameter control the handling of arithmetic exceptions:

BigDecimal::EXCEPTION_NaN BigDecimal::EXCEPTION_INFINITY
BigDecimal::EXCEPTION_UNDERFLOW BigDecimal::EXCEPTION_OVERFLOW
BigDecimal::EXCEPTION_ZERODIVIDE BigDecimal::EXCEPTION_ALL

For each mode parameter above, if the value set is false, computation continues after an arithmetic exception of the appropriate type. When computation continues, results are as follows:

EXCEPTION_NaN

NaN

EXCEPTION_INFINITY

+infinity or -infinity

EXCEPTION_UNDERFLOW

0

EXCEPTION_OVERFLOW

+infinity or -infinity

EXCEPTION_ZERODIVIDE

+infinity or -infinity

One value of the mode parameter controls the rounding of numeric values: BigDecimal::ROUND_MODE. The values it can take are:

ROUND_UP, :up

round away from zero

ROUND_DOWN, :down, :truncate

round towards zero (truncate)

ROUND_HALF_UP, :half_up, :default

round towards the nearest neighbor, unless both neighbors are equidistant, in which case round away from zero. (default)

ROUND_HALF_DOWN, :half_down

round towards the nearest neighbor, unless both neighbors are equidistant, in which case round towards zero.

ROUND_HALF_EVEN, :half_even, :banker

round towards the nearest neighbor, unless both neighbors are equidistant, in which case round towards the even neighbor (Banker's rounding)

ROUND_CEILING, :ceiling, :ceil

round towards positive infinity (ceil)

ROUND_FLOOR, :floor

round towards negative infinity (floor)

static VALUE
BigDecimal_mode(int argc, VALUE *argv, VALUE self)
{
    VALUE which;
    VALUE val;
    unsigned long f,fo;

    if(rb_scan_args(argc,argv,"11",&which,&val)==1) val = Qnil;

    Check_Type(which, T_FIXNUM);
    f = (unsigned long)FIX2INT(which);

    if(f&VP_EXCEPTION_ALL) {
        /* Exception mode setting */
        fo = VpGetException();
        if(val==Qnil) return INT2FIX(fo);
        if(val!=Qfalse && val!=Qtrue) {
            rb_raise(rb_eArgError, "second argument must be true or false");
            return Qnil; /* Not reached */
        }
        if(f&VP_EXCEPTION_INFINITY) {
            VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_INFINITY):
                           (fo&(~VP_EXCEPTION_INFINITY))));
        }
        fo = VpGetException();
        if(f&VP_EXCEPTION_NaN) {
            VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_NaN):
                           (fo&(~VP_EXCEPTION_NaN))));
        }
        fo = VpGetException();
        if(f&VP_EXCEPTION_UNDERFLOW) {
            VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_UNDERFLOW):
                           (fo&(~VP_EXCEPTION_UNDERFLOW))));
        }
        fo = VpGetException();
        if(f&VP_EXCEPTION_ZERODIVIDE) {
            VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_ZERODIVIDE):
                           (fo&(~VP_EXCEPTION_ZERODIVIDE))));
        }
        fo = VpGetException();
        return INT2FIX(fo);
    }
    if (VP_ROUND_MODE == f) {
        /* Rounding mode setting */
        unsigned short sw;
        fo = VpGetRoundMode();
        if (NIL_P(val)) return INT2FIX(fo);
        sw = check_rounding_mode(val);
        fo = VpSetRoundMode(sw);
        return INT2FIX(fo);
    }
    rb_raise(rb_eTypeError, "first argument for BigDecimal#mode invalid");
    return Qnil;
}
new(initial, digits) click to toggle source

Create a new BigDecimal object.

initial

The initial value, as an Integer, a Float, a Rational, a BigDecimal, or a String.

If it is a String, spaces are ignored and unrecognized characters terminate the value.

digits

The number of significant digits, as a Fixnum. If omitted or 0, the number of significant digits is determined from the initial value.

The actual number of significant digits used in computation is usually larger than the specified number.

static VALUE
BigDecimal_initialize(int argc, VALUE *argv, VALUE self)
{
    ENTER(1);
    Real *pv = rb_check_typeddata(self, &BigDecimal_data_type);
    Real *x;

    GUARD_OBJ(x, BigDecimal_new(argc, argv));
    if (ToValue(x)) {
        pv = VpCopy(pv, x);
    }
    else {
        VpFree(pv);
        pv = x;
    }
    DATA_PTR(self) = pv;
    pv->obj = self;
    return self;
}
save_exception_mode { ... } click to toggle source

Excecute the provided block, but preserve the exception mode

BigDecimal.save_exception_mode do
  BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)

  BigDecimal.new(BigDecimal('Infinity'))
  BigDecimal.new(BigDecimal('-Infinity'))
  BigDecimal(BigDecimal.new('NaN'))
end

For use with the BigDecimal::EXCEPTION_*

See ::mode

static VALUE
BigDecimal_save_exception_mode(VALUE self)
{
    unsigned short const exception_mode = VpGetException();
    int state;
    VALUE ret = rb_protect(rb_yield, Qnil, &state);
    VpSetException(exception_mode);
    if (state) rb_jump_tag(state);
    return ret;
}
save_limit { ... } click to toggle source

Excecute the provided block, but preserve the precision limit

BigDecimal.limit(100)
puts BigDecimal.limit
BigDecimal.save_limit do
    BigDecimal.limit(200)
    puts BigDecimal.limit
end
puts BigDecimal.limit
static VALUE
BigDecimal_save_limit(VALUE self)
{
    size_t const limit = VpGetPrecLimit();
    int state;
    VALUE ret = rb_protect(rb_yield, Qnil, &state);
    VpSetPrecLimit(limit);
    if (state) rb_jump_tag(state);
    return ret;
}
save_rounding_mode { ... } click to toggle source

Excecute the provided block, but preserve the rounding mode

BigDecimal.save_exception_mode do
  BigDecimal.mode(BigDecimal::ROUND_MODE, :up)
  puts BigDecimal.mode(BigDecimal::ROUND_MODE)
end

For use with the BigDecimal::ROUND_*

See ::mode

static VALUE
BigDecimal_save_rounding_mode(VALUE self)
{
    unsigned short const round_mode = VpGetRoundMode();
    int state;
    VALUE ret = rb_protect(rb_yield, Qnil, &state);
    VpSetRoundMode(round_mode);
    if (state) rb_jump_tag(state);
    return ret;
}
ver() click to toggle source

Returns the BigDecimal version number.

static VALUE
BigDecimal_version(VALUE self)
{
    /*
     * 1.0.0: Ruby 1.8.0
     * 1.0.1: Ruby 1.8.1
     * 1.1.0: Ruby 1.9.3
    */
    return rb_str_new2("1.1.0");
}

Public Instance Methods

a % b click to toggle source
modulo(b)

Returns the modulus from dividing by b.

See #divmod.

static VALUE
BigDecimal_mod(VALUE self, VALUE r)
mult(value, digits) click to toggle source

Multiply by the specified value.

e.g.

c = a.mult(b,n)
c = a * b
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to ::mode.

static VALUE
BigDecimal_mult(VALUE self, VALUE r)
{
    ENTER(5);
    Real *c, *a, *b;
    size_t mx;

    GUARD_OBJ(a,GetVpValue(self,1));
    if (RB_TYPE_P(r, T_FLOAT)) {
        b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
    }
    else if (RB_TYPE_P(r, T_RATIONAL)) {
        b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
    }
    else {
        b = GetVpValue(r,0);
    }

    if(!b) return DoSomeOne(self,r,'*');
    SAVE(b);

    mx = a->Prec + b->Prec;
    GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0"));
    VpMult(c, a, b);
    return ToValue(c);
}
big_decimal ** exp → big_decimal click to toggle source

It is a synonym of #power.

static VALUE
BigDecimal_power_op(VALUE self, VALUE exp)
{
    return BigDecimal_power(1, &exp, self);
}
add(value, digits) click to toggle source

Add the specified value.

e.g.

c = a.add(b,n)
c = a + b
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to ::mode.

static VALUE
BigDecimal_add(VALUE self, VALUE r)
{
    ENTER(5);
    Real *c, *a, *b;
    size_t mx;

    GUARD_OBJ(a, GetVpValue(self, 1));
    if (RB_TYPE_P(r, T_FLOAT)) {
        b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
    }
    else if (RB_TYPE_P(r, T_RATIONAL)) {
        b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
    }
    else {
        b = GetVpValue(r,0);
    }

    if (!b) return DoSomeOne(self,r,'+');
    SAVE(b);

    if (VpIsNaN(b)) return b->obj;
    if (VpIsNaN(a)) return a->obj;

    mx = GetAddSubPrec(a, b);
    if (mx == (size_t)-1L) {
        GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0"));
        VpAddSub(c, a, b, 1);
    }
    else {
        GUARD_OBJ(c, VpCreateRbObject(mx * (VpBaseFig() + 1), "0"));
        if(!mx) {
            VpSetInf(c, VpGetSign(a));
        }
        else {
            VpAddSub(c, a, b, 1);
        }
    }
    return ToValue(c);
}
+@ click to toggle source

Return self.

e.g.

b = +a  # b == a
static VALUE
BigDecimal_uplus(VALUE self)
{
    return self;
}
sub(value, digits) click to toggle source

Subtract the specified value.

e.g.

c = a.sub(b,n)
c = a - b
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to ::mode.

static VALUE
BigDecimal_sub(VALUE self, VALUE r)
{
    ENTER(5);
    Real *c, *a, *b;
    size_t mx;

    GUARD_OBJ(a,GetVpValue(self,1));
    if (RB_TYPE_P(r, T_FLOAT)) {
        b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
    }
    else if (RB_TYPE_P(r, T_RATIONAL)) {
        b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
    }
    else {
        b = GetVpValue(r,0);
    }

    if(!b) return DoSomeOne(self,r,'-');
    SAVE(b);

    if(VpIsNaN(b)) return b->obj;
    if(VpIsNaN(a)) return a->obj;

    mx = GetAddSubPrec(a,b);
    if (mx == (size_t)-1L) {
        GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0"));
        VpAddSub(c, a, b, -1);
    } else {
        GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0"));
        if(!mx) {
            VpSetInf(c,VpGetSign(a));
        } else {
            VpAddSub(c, a, b, -1);
        }
    }
    return ToValue(c);
}
-@ click to toggle source

Return the negation of self.

e.g.

b = -a
b == a * -1
static VALUE
BigDecimal_neg(VALUE self)
{
    ENTER(5);
    Real *c, *a;
    GUARD_OBJ(a,GetVpValue(self,1));
    GUARD_OBJ(c,VpCreateRbObject(a->Prec *(VpBaseFig() + 1), "0"));
    VpAsgn(c, a, -1);
    return ToValue(c);
}
div(value, digits) click to toggle source
quo(value)

Divide by the specified value.

e.g.

c = a.div(b,n)
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to ::mode.

If digits is 0, the result is the same as the / operator. If not, the result is an integer BigDecimal, by analogy with Float#div.

The alias quo is provided since div(value, 0) is the same as computing the quotient; see #divmod.

static VALUE
BigDecimal_div(VALUE self, VALUE r)
/* For c = self/r: with round operation */
{
    ENTER(5);
    Real *c=NULL, *res=NULL, *div = NULL;
    r = BigDecimal_divide(&c, &res, &div, self, r);
    if(r!=(VALUE)0) return r; /* coerced by other */
    SAVE(c);SAVE(res);SAVE(div);
    /* a/b = c + r/b */
    /* c xxxxx
       r 00000yyyyy  ==> (y/b)*BASE >= HALF_BASE
     */
    /* Round */
    if(VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */
        VpInternalRound(c, 0, c->frac[c->Prec-1], (BDIGIT)(VpBaseVal()*(BDIGIT_DBL)res->frac[0]/div->frac[0]));
    }
    return ToValue(c);
}
a < b click to toggle source

Returns true if a is less than b.

Values may be coerced to perform the comparison (see ==, #coerce).

static VALUE
BigDecimal_lt(VALUE self, VALUE r)
{
    return BigDecimalCmp(self, r, '<');
}
a <= b click to toggle source

Returns true if a is less than or equal to b.

Values may be coerced to perform the comparison (see ==, #coerce).

static VALUE
BigDecimal_le(VALUE self, VALUE r)
{
    return BigDecimalCmp(self, r, 'L');
}
<=>(p1) click to toggle source

The comparison operator. a <=> b is 0 if a == b, 1 if a > b, -1 if a < b.

static VALUE
BigDecimal_comp(VALUE self, VALUE r)
{
    return BigDecimalCmp(self, r, '*');
}
==(p1) click to toggle source

Tests for value equality; returns true if the values are equal.

The == and === operators and the eql? method have the same implementation for BigDecimal.

Values may be coerced to perform the comparison:

::new('1.0') == 1.0 -> true

static VALUE
BigDecimal_eq(VALUE self, VALUE r)
{
    return BigDecimalCmp(self, r, '=');
}
===(p1) click to toggle source

Tests for value equality; returns true if the values are equal.

The == and === operators and the eql? method have the same implementation for BigDecimal.

Values may be coerced to perform the comparison:

::new('1.0') == 1.0 -> true

static VALUE
BigDecimal_eq(VALUE self, VALUE r)
{
    return BigDecimalCmp(self, r, '=');
}
a > b click to toggle source

Returns true if a is greater than b.

Values may be coerced to perform the comparison (see ==, #coerce).

static VALUE
BigDecimal_gt(VALUE self, VALUE r)
{
    return BigDecimalCmp(self, r, '>');
}
a >= b click to toggle source

Returns true if a is greater than or equal to b.

Values may be coerced to perform the comparison (see ==, #coerce)

static VALUE
BigDecimal_ge(VALUE self, VALUE r)
{
    return BigDecimalCmp(self, r, 'G');
}
_dump click to toggle source

Method used to provide marshalling support.

inf = BigDecimal.new('Infinity')
=> #<BigDecimal:1e16fa8,'Infinity',9(9)>
BigDecimal._load(inf._dump)
=> #<BigDecimal:1df8dc8,'Infinity',9(9)>

See the Marshal module.

static VALUE
BigDecimal_dump(int argc, VALUE *argv, VALUE self)
{
    ENTER(5);
    Real *vp;
    char *psz;
    VALUE dummy;
    volatile VALUE dump;

    rb_scan_args(argc, argv, "01", &dummy);
    GUARD_OBJ(vp,GetVpValue(self,1));
    dump = rb_str_new(0,VpNumOfChars(vp,"E")+50);
    psz = RSTRING_PTR(dump);
    sprintf(psz, "%"PRIuSIZE":", VpMaxPrec(vp)*VpBaseFig());
    VpToString(vp, psz+strlen(psz), 0, 0);
    rb_str_resize(dump, strlen(psz));
    return dump;
}
abs() click to toggle source

Returns the absolute value.

BigDecimal('5').abs -> 5

BigDecimal('-3').abs -> 3

static VALUE
BigDecimal_abs(VALUE self)
{
    ENTER(5);
    Real *c, *a;
    size_t mx;

    GUARD_OBJ(a,GetVpValue(self,1));
    mx = a->Prec *(VpBaseFig() + 1);
    GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
    VpAsgn(c, a, 1);
    VpChangeSign(c, 1);
    return ToValue(c);
}
add(value, digits) click to toggle source
+

Add the specified value.

e.g.

c = a.add(b,n)
c = a + b
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to ::mode.

static VALUE
BigDecimal_add2(VALUE self, VALUE b, VALUE n)
{
    ENTER(2);
    Real   *cv;
    SIGNED_VALUE mx = GetPositiveInt(n);
    if (mx == 0) return BigDecimal_add(self, b);
    else {
       size_t pl = VpSetPrecLimit(0);
       VALUE   c = BigDecimal_add(self,b);
       VpSetPrecLimit(pl);
       GUARD_OBJ(cv,GetVpValue(c,1));
       VpLeftRound(cv,VpGetRoundMode(),mx);
       return ToValue(cv);
    }
}
as_json(*) click to toggle source

Marshal the object to JSON.

method used for JSON marshalling support.

# File ext/json/lib/json/add/bigdecimal.rb, line 17
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'b'            => _dump,
  }
end
ceil(n) click to toggle source

Return the smallest integer greater than or equal to the value, as a BigDecimal.

BigDecimal('3.14159').ceil #=> 4
BigDecimal('-9.1').ceil #=> -9

If n is specified and positive, the fractional part of the result has no more than that many digits.

If n is specified and negative, at least that many digits to the left of the decimal point will be 0 in the result.

BigDecimal('3.14159').ceil(3) #=> 3.142
BigDecimal('13345.234').ceil(-2) #=> 13400.0

static VALUE
BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
{
    ENTER(5);
    Real *c, *a;
    int iLoc;
    VALUE vLoc;
    size_t mx, pl = VpSetPrecLimit(0);

    if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
        iLoc = 0;
    } else {
        Check_Type(vLoc, T_FIXNUM);
        iLoc = FIX2INT(vLoc);
    }

    GUARD_OBJ(a,GetVpValue(self,1));
    mx = a->Prec *(VpBaseFig() + 1);
    GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
    VpSetPrecLimit(pl);
    VpActiveRound(c,a,VP_ROUND_CEIL,iLoc);
    if (argc == 0) {
        return BigDecimal_to_i(ToValue(c));
    }
    return ToValue(c);
}
coerce(p1) click to toggle source

The coerce method provides support for Ruby type coercion. It is not enabled by default.

This means that binary operations like + * / or - can often be performed on a BigDecimal and an object of another type, if the other object can be coerced into a BigDecimal value.

e.g. a = ::new(“1.0”) b = a / 2.0 -> 0.5

Note that coercing a String to a BigDecimal is not supported by default; it requires a special compile-time option when building Ruby.

static VALUE
BigDecimal_coerce(VALUE self, VALUE other)
{
    ENTER(2);
    VALUE obj;
    Real *b;

    if (RB_TYPE_P(other, T_FLOAT)) {
        obj = rb_assoc_new(other, BigDecimal_to_f(self));
    }
    else {
        if (RB_TYPE_P(other, T_RATIONAL)) {
            Real* pv = DATA_PTR(self);
            GUARD_OBJ(b, GetVpValueWithPrec(other, pv->Prec*VpBaseFig(), 1));
        }
        else {
            GUARD_OBJ(b, GetVpValue(other, 1));
        }
        obj = rb_assoc_new(b->obj, self);
    }

    return obj;
}
div(p1, p2 = v2) click to toggle source

See #quo

static VALUE
BigDecimal_div2(int argc, VALUE *argv, VALUE self)
{
    ENTER(5);
    VALUE b,n;
    int na = rb_scan_args(argc,argv,"11",&b,&n);
    if(na==1) { /* div in Float sense */
       Real *div=NULL;
       Real *mod;
       if(BigDecimal_DoDivmod(self,b,&div,&mod)) {
          return BigDecimal_to_i(ToValue(div));
       }
       return DoSomeOne(self,b,rb_intern("div"));
    } else {    /* div in BigDecimal sense */
       SIGNED_VALUE ix = GetPositiveInt(n);
       if (ix == 0) return BigDecimal_div(self, b);
       else {
          Real *res=NULL;
          Real *av=NULL, *bv=NULL, *cv=NULL;
          size_t mx = (ix+VpBaseFig()*2);
          size_t pl = VpSetPrecLimit(0);

          GUARD_OBJ(cv,VpCreateRbObject(mx,"0"));
          GUARD_OBJ(av,GetVpValue(self,1));
          GUARD_OBJ(bv,GetVpValue(b,1));
          mx = av->Prec + bv->Prec + 2;
          if(mx <= cv->MaxPrec) mx = cv->MaxPrec+1;
          GUARD_OBJ(res,VpCreateRbObject((mx * 2  + 2)*VpBaseFig(), "#0"));
          VpDivd(cv,res,av,bv);
          VpSetPrecLimit(pl);
          VpLeftRound(cv,VpGetRoundMode(),ix);
          return ToValue(cv);
       }
    }
}
divmod(p1) click to toggle source

Divides by the specified value, and returns the quotient and modulus as BigDecimal numbers. The quotient is rounded towards negative infinity.

For example:

require 'bigdecimal'

a = ::new(“42”) b = ::new(“9”)

q,m = a.divmod(b)

c = q * b + m

a == c -> true

The quotient q is (a/b).floor, and the modulus is the amount that must be added to q * b to get a.

static VALUE
BigDecimal_divmod(VALUE self, VALUE r)
{
    ENTER(5);
    Real *div=NULL, *mod=NULL;

    if(BigDecimal_DoDivmod(self,r,&div,&mod)) {
        SAVE(div); SAVE(mod);
        return rb_assoc_new(ToValue(div), ToValue(mod));
    }
    return DoSomeOne(self,r,rb_intern("divmod"));
}
eql?(p1) click to toggle source

Tests for value equality; returns true if the values are equal.

The == and === operators and the eql? method have the same implementation for BigDecimal.

Values may be coerced to perform the comparison:

::new('1.0') == 1.0 -> true

static VALUE
BigDecimal_eq(VALUE self, VALUE r)
{
    return BigDecimalCmp(self, r, '=');
}
exponent() click to toggle source

Returns the exponent of the BigDecimal number, as an Integer.

If the number can be represented as 0.xxxxxx*10**n where xxxxxx is a string of digits with no leading zeros, then n is the exponent.

static VALUE
BigDecimal_exponent(VALUE self)
{
    ssize_t e = VpExponent10(GetVpValue(self, 1));
    return INT2NUM(e);
}
finite?() click to toggle source

Returns True if the value is finite (not NaN or infinite)

static VALUE
BigDecimal_IsFinite(VALUE self)
{
    Real *p = GetVpValue(self,1);
    if(VpIsNaN(p)) return Qfalse;
    if(VpIsInf(p)) return Qfalse;
    return Qtrue;
}
fix() click to toggle source

Return the integer part of the number.

static VALUE
BigDecimal_fix(VALUE self)
{
    ENTER(5);
    Real *c, *a;
    size_t mx;

    GUARD_OBJ(a,GetVpValue(self,1));
    mx = a->Prec *(VpBaseFig() + 1);
    GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
    VpActiveRound(c,a,VP_ROUND_DOWN,0); /* 0: round off */
    return ToValue(c);
}
floor(n) click to toggle source

Return the largest integer less than or equal to the value, as a BigDecimal.

BigDecimal('3.14159').floor #=> 3
BigDecimal('-9.1').floor #=> -10

If n is specified and positive, the fractional part of the result has no more than that many digits.

If n is specified and negative, at least that many digits to the left of the decimal point will be 0 in the result.

BigDecimal('3.14159').floor(3) #=> 3.141
BigDecimal('13345.234').floor(-2) #=> 13300.0

static VALUE
BigDecimal_floor(int argc, VALUE *argv, VALUE self)
{
    ENTER(5);
    Real *c, *a;
    int iLoc;
    VALUE vLoc;
    size_t mx, pl = VpSetPrecLimit(0);

    if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
        iLoc = 0;
    } else {
        Check_Type(vLoc, T_FIXNUM);
        iLoc = FIX2INT(vLoc);
    }

    GUARD_OBJ(a,GetVpValue(self,1));
    mx = a->Prec *(VpBaseFig() + 1);
    GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
    VpSetPrecLimit(pl);
    VpActiveRound(c,a,VP_ROUND_FLOOR,iLoc);
#ifdef BIGDECIMAL_DEBUG
    VPrint(stderr, "floor: c=%\n", c);
#endif
    if (argc == 0) {
        return BigDecimal_to_i(ToValue(c));
    }
    return ToValue(c);
}
frac() click to toggle source

Return the fractional part of the number.

static VALUE
BigDecimal_frac(VALUE self)
{
    ENTER(5);
    Real *c, *a;
    size_t mx;

    GUARD_OBJ(a,GetVpValue(self,1));
    mx = a->Prec *(VpBaseFig() + 1);
    GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
    VpFrac(c, a);
    return ToValue(c);
}
hash click to toggle source

Creates a hash for this BigDecimal.

Two BigDecimals with equal sign, fractional part and exponent have the same hash.

static VALUE
BigDecimal_hash(VALUE self)
{
    ENTER(1);
    Real *p;
    st_index_t hash;

    GUARD_OBJ(p,GetVpValue(self,1));
    hash = (st_index_t)p->sign;
    /* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */
    if(hash == 2 || hash == (st_index_t)-2) {
        hash ^= rb_memhash(p->frac, sizeof(BDIGIT)*p->Prec);
        hash += p->exponent;
    }
    return INT2FIX(hash);
}
infinite?() click to toggle source

Returns nil, -1, or +1 depending on whether the value is finite, -infinity, or +infinity.

static VALUE
BigDecimal_IsInfinite(VALUE self)
{
    Real *p = GetVpValue(self,1);
    if(VpIsPosInf(p)) return INT2FIX(1);
    if(VpIsNegInf(p)) return INT2FIX(-1);
    return Qnil;
}
inspect() click to toggle source

Returns debugging information about the value as a string of comma-separated values in angle brackets with a leading #:

::new(“1234.5678”).inspect -> “#<BigDecimal:b7ea1130,'0.12345678E4',8(12)>”

The first part is the address, the second is the value as a string, and the final part ss(mm) is the current number of significant digits and the maximum number of significant digits, respectively.

static VALUE
BigDecimal_inspect(VALUE self)
{
    ENTER(5);
    Real *vp;
    volatile VALUE obj;
    size_t nc;
    char *psz, *tmp;

    GUARD_OBJ(vp,GetVpValue(self,1));
    nc = VpNumOfChars(vp,"E");
    nc +=(nc + 9) / 10;

    obj = rb_str_new(0, nc+256);
    psz = RSTRING_PTR(obj);
    sprintf(psz,"#<BigDecimal:%"PRIxVALUE",'",self);
    tmp = psz + strlen(psz);
    VpToString(vp, tmp, 10, 0);
    tmp += strlen(tmp);
    sprintf(tmp, "',%"PRIuSIZE"(%"PRIuSIZE")>", VpPrec(vp)*VpBaseFig(), VpMaxPrec(vp)*VpBaseFig());
    rb_str_resize(obj, strlen(psz));
    return obj;
}
a % b click to toggle source
modulo(b)

Returns the modulus from dividing by b.

See #divmod.

static VALUE
BigDecimal_mod(VALUE self, VALUE r)
mult(value, digits) click to toggle source

Multiply by the specified value.

e.g.

c = a.mult(b,n)
c = a * b
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to ::mode.

static VALUE
BigDecimal_mult2(VALUE self, VALUE b, VALUE n)
{
    ENTER(2);
    Real *cv;
    SIGNED_VALUE mx = GetPositiveInt(n);
    if (mx == 0) return BigDecimal_mult(self, b);
    else {
       size_t pl = VpSetPrecLimit(0);
       VALUE   c = BigDecimal_mult(self,b);
       VpSetPrecLimit(pl);
       GUARD_OBJ(cv,GetVpValue(c,1));
       VpLeftRound(cv,VpGetRoundMode(),mx);
       return ToValue(cv);
    }
}
nan?() click to toggle source

Returns True if the value is Not a Number

static VALUE
BigDecimal_IsNaN(VALUE self)
{
    Real *p = GetVpValue(self,1);
    if(VpIsNaN(p))  return Qtrue;
    return Qfalse;
}
nonzero?() click to toggle source

Returns self if the value is non-zero, nil otherwise.

static VALUE
BigDecimal_nonzero(VALUE self)
{
    Real *a = GetVpValue(self,1);
    return VpIsZero(a) ? Qnil : self;
}
power(n) click to toggle source
power(n, prec)

Returns the value raised to the power of n.

Note that n must be an Integer.

Also available as the operator **

static VALUE
BigDecimal_power(int argc, VALUE*argv, VALUE self)
{
    ENTER(5);
    VALUE vexp, prec;
    Real* exp = NULL;
    Real *x, *y;
    ssize_t mp, ma, n;
    SIGNED_VALUE int_exp;
    double d;

    rb_scan_args(argc, argv, "11", &vexp, &prec);

    GUARD_OBJ(x, GetVpValue(self, 1));
    n = NIL_P(prec) ? (ssize_t)(x->Prec*VpBaseFig()) : NUM2SSIZET(prec);

    if (VpIsNaN(x)) {
        y = VpCreateRbObject(n, "0#");
        RB_GC_GUARD(y->obj);
        VpSetNaN(y);
        return ToValue(y);
    }

retry:
    switch (TYPE(vexp)) {
      case T_FIXNUM:
        break;

      case T_BIGNUM:
        break;

      case T_FLOAT:
        d = RFLOAT_VALUE(vexp);
        if (d == round(d)) {
            vexp = LL2NUM((LONG_LONG)round(d));
            goto retry;
        }
        exp = GetVpValueWithPrec(vexp, DBL_DIG+1, 1);
        break;

      case T_RATIONAL:
        if (is_zero(RRATIONAL(vexp)->num)) {
            if (is_positive(vexp)) {
                vexp = INT2FIX(0);
                goto retry;
            }
        }
        else if (is_one(RRATIONAL(vexp)->den)) {
            vexp = RRATIONAL(vexp)->num;
            goto retry;
        }
        exp = GetVpValueWithPrec(vexp, n, 1);
        break;

      case T_DATA:
        if (is_kind_of_BigDecimal(vexp)) {
            VALUE zero = INT2FIX(0);
            VALUE rounded = BigDecimal_round(1, &zero, vexp);
            if (RTEST(BigDecimal_eq(vexp, rounded))) {
                vexp = BigDecimal_to_i(vexp);
                goto retry;
            }
            exp = DATA_PTR(vexp);
            break;
        }
        /* fall through */
      default:
        rb_raise(rb_eTypeError,
                 "wrong argument type %"PRIsVALUE" (expected scalar Numeric)",
                 RB_OBJ_CLASSNAME(vexp));
    }

    if (VpIsZero(x)) {
        if (is_negative(vexp)) {
            y = VpCreateRbObject(n, "#0");
            RB_GC_GUARD(y->obj);
            if (VpGetSign(x) < 0) {
                if (is_integer(vexp)) {
                    if (is_even(vexp)) {
                        /* (-0) ** (-even_integer)  -> Infinity */
                        VpSetPosInf(y);
                    }
                    else {
                        /* (-0) ** (-odd_integer)  -> -Infinity */
                        VpSetNegInf(y);
                    }
                }
                else {
                    /* (-0) ** (-non_integer)  -> Infinity */
                    VpSetPosInf(y);
                }
            }
            else {
                /* (+0) ** (-num)  -> Infinity */
                VpSetPosInf(y);
            }
            return ToValue(y);
        }
        else if (is_zero(vexp)) {
            return ToValue(VpCreateRbObject(n, "1"));
        }
        else {
            return ToValue(VpCreateRbObject(n, "0"));
        }
    }

    if (is_zero(vexp)) {
        return ToValue(VpCreateRbObject(n, "1"));
    }
    else if (is_one(vexp)) {
        return self;
    }

    if (VpIsInf(x)) {
        if (is_negative(vexp)) {
            if (VpGetSign(x) < 0) {
                if (is_integer(vexp)) {
                    if (is_even(vexp)) {
                        /* (-Infinity) ** (-even_integer) -> +0 */
                        return ToValue(VpCreateRbObject(n, "0"));
                    }
                    else {
                        /* (-Infinity) ** (-odd_integer) -> -0 */
                        return ToValue(VpCreateRbObject(n, "-0"));
                    }
                }
                else {
                    /* (-Infinity) ** (-non_integer) -> -0 */
                    return ToValue(VpCreateRbObject(n, "-0"));
                }
            }
            else {
                return ToValue(VpCreateRbObject(n, "0"));
            }
        }
        else {
            y = VpCreateRbObject(n, "0#");
            if (VpGetSign(x) < 0) {
                if (is_integer(vexp)) {
                    if (is_even(vexp)) {
                        VpSetPosInf(y);
                    }
                    else {
                        VpSetNegInf(y);
                    }
                }
                else {
                    /* TODO: support complex */
                    rb_raise(rb_eMathDomainError,
                             "a non-integral exponent for a negative base");
                }
            }
            else {
                VpSetPosInf(y);
            }
            return ToValue(y);
        }
    }

    if (exp != NULL) {
        return rmpd_power_by_big_decimal(x, exp, n);
    }
    else if (RB_TYPE_P(vexp, T_BIGNUM)) {
        VALUE abs_value = BigDecimal_abs(self);
        if (is_one(abs_value)) {
            return ToValue(VpCreateRbObject(n, "1"));
        }
        else if (RTEST(rb_funcall(abs_value, '<', 1, INT2FIX(1)))) {
            if (is_negative(vexp)) {
                y = VpCreateRbObject(n, "0#");
                if (is_even(vexp)) {
                    VpSetInf(y, VpGetSign(x));
                }
                else {
                    VpSetInf(y, -VpGetSign(x));
                }
                return ToValue(y);
            }
            else if (VpGetSign(x) < 0 && is_even(vexp)) {
                return ToValue(VpCreateRbObject(n, "-0"));
            }
            else {
                return ToValue(VpCreateRbObject(n, "0"));
            }
        }
        else {
            if (is_positive(vexp)) {
                y = VpCreateRbObject(n, "0#");
                if (is_even(vexp)) {
                    VpSetInf(y, VpGetSign(x));
                }
                else {
                    VpSetInf(y, -VpGetSign(x));
                }
                return ToValue(y);
            }
            else if (VpGetSign(x) < 0 && is_even(vexp)) {
                return ToValue(VpCreateRbObject(n, "-0"));
            }
            else {
                return ToValue(VpCreateRbObject(n, "0"));
            }
        }
    }

    int_exp = FIX2INT(vexp);
    ma = int_exp;
    if (ma < 0)  ma = -ma;
    if (ma == 0) ma = 1;

    if (VpIsDef(x)) {
        mp = x->Prec * (VpBaseFig() + 1);
        GUARD_OBJ(y, VpCreateRbObject(mp * (ma + 1), "0"));
    }
    else {
        GUARD_OBJ(y, VpCreateRbObject(1, "0"));
    }
    VpPower(y, x, int_exp);
    return ToValue(y);
}
precs click to toggle source

Returns an Array of two Integer values.

The first value is the current number of significant digits in the BigDecimal. The second value is the maximum number of significant digits for the BigDecimal.

static VALUE
BigDecimal_prec(VALUE self)
{
    ENTER(1);
    Real *p;
    VALUE obj;

    GUARD_OBJ(p,GetVpValue(self,1));
    obj = rb_assoc_new(INT2NUM(p->Prec*VpBaseFig()),
                       INT2NUM(p->MaxPrec*VpBaseFig()));
    return obj;
}
div(value, digits) click to toggle source
quo(value)

Divide by the specified value.

e.g.

c = a.div(b,n)
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to ::mode.

If digits is 0, the result is the same as the / operator. If not, the result is an integer BigDecimal, by analogy with Float#div.

The alias quo is provided since div(value, 0) is the same as computing the quotient; see #divmod.

static VALUE
BigDecimal_div(VALUE self, VALUE r)
/* For c = self/r: with round operation */
{
    ENTER(5);
    Real *c=NULL, *res=NULL, *div = NULL;
    r = BigDecimal_divide(&c, &res, &div, self, r);
    if(r!=(VALUE)0) return r; /* coerced by other */
    SAVE(c);SAVE(res);SAVE(div);
    /* a/b = c + r/b */
    /* c xxxxx
       r 00000yyyyy  ==> (y/b)*BASE >= HALF_BASE
     */
    /* Round */
    if(VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */
        VpInternalRound(c, 0, c->frac[c->Prec-1], (BDIGIT)(VpBaseVal()*(BDIGIT_DBL)res->frac[0]/div->frac[0]));
    }
    return ToValue(c);
}
remainder(p1) click to toggle source

Returns the remainder from dividing by the value.

x.remainder(y) means x-y*(x/y).truncate

static VALUE
BigDecimal_remainder(VALUE self, VALUE r) /* remainder */
{
    VALUE  f;
    Real  *d,*rv=0;
    f = BigDecimal_divremain(self,r,&d,&rv);
    if(f!=(VALUE)0) return f;
    return ToValue(rv);
}
round(n, mode) click to toggle source

Round to the nearest 1 (by default), returning the result as a BigDecimal.

BigDecimal('3.14159').round #=> 3
BigDecimal('8.7').round #=> 9

If n is specified and positive, the fractional part of the result has no more than that many digits.

If n is specified and negative, at least that many digits to the left of the decimal point will be 0 in the result.

BigDecimal('3.14159').round(3) #=> 3.142
BigDecimal('13345.234').round(-2) #=> 13300.0

The value of the optional mode argument can be used to determine how rounding is performed; see ::mode.

static VALUE
BigDecimal_round(int argc, VALUE *argv, VALUE self)
{
    ENTER(5);
    Real   *c, *a;
    int    iLoc = 0;
    VALUE  vLoc;
    VALUE  vRound;
    size_t mx, pl;

    unsigned short sw = VpGetRoundMode();

    switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) {
    case 0:
        iLoc = 0;
        break;
    case 1:
        Check_Type(vLoc, T_FIXNUM);
        iLoc = FIX2INT(vLoc);
        break;
    case 2:
        Check_Type(vLoc, T_FIXNUM);
        iLoc = FIX2INT(vLoc);
        sw = check_rounding_mode(vRound);
        break;
    }

    pl = VpSetPrecLimit(0);
    GUARD_OBJ(a,GetVpValue(self,1));
    mx = a->Prec *(VpBaseFig() + 1);
    GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
    VpSetPrecLimit(pl);
    VpActiveRound(c,a,sw,iLoc);
    if (argc == 0) {
        return BigDecimal_to_i(ToValue(c));
    }
    return ToValue(c);
}
sign() click to toggle source

Returns the sign of the value.

Returns a positive value if > 0, a negative value if < 0, and a zero if == 0.

The specific value returned indicates the type and sign of the BigDecimal, as follows:

BigDecimal::SIGN_NaN

value is Not a Number

BigDecimal::SIGN_POSITIVE_ZERO

value is +0

BigDecimal::SIGN_NEGATIVE_ZERO

value is -0

BigDecimal::SIGN_POSITIVE_INFINITE

value is +infinity

BigDecimal::SIGN_NEGATIVE_INFINITE

value is -infinity

BigDecimal::SIGN_POSITIVE_FINITE

value is positive

BigDecimal::SIGN_NEGATIVE_FINITE

value is negative

static VALUE
BigDecimal_sign(VALUE self)
{ /* sign */
    int s = GetVpValue(self,1)->sign;
    return INT2FIX(s);
}
split() click to toggle source

Splits a BigDecimal number into four parts, returned as an array of values.

The first value represents the sign of the BigDecimal, and is -1 or 1, or 0 if the BigDecimal is Not a Number.

The second value is a string representing the significant digits of the BigDecimal, with no leading zeros.

The third value is the base used for arithmetic (currently always 10) as an Integer.

The fourth value is an Integer exponent.

If the BigDecimal can be represented as 0.xxxxxx*10**n, then xxxxxx is the string of significant digits with no leading zeros, and n is the exponent.

From these values, you can translate a BigDecimal to a float as follows:

sign, significant_digits, base, exponent = a.split
f = sign * "0.#{significant_digits}".to_f * (base ** exponent)

(Note that the #to_f method is provided as a more convenient way to translate a BigDecimal to a Float.)

static VALUE
BigDecimal_split(VALUE self)
{
    ENTER(5);
    Real *vp;
    VALUE obj,str;
    ssize_t e, s;
    char *psz1;

    GUARD_OBJ(vp,GetVpValue(self,1));
    str = rb_str_new(0, VpNumOfChars(vp,"E"));
    psz1 = RSTRING_PTR(str);
    VpSzMantissa(vp,psz1);
    s = 1;
    if(psz1[0]=='-') {
        size_t len = strlen(psz1+1);

        memmove(psz1, psz1+1, len);
        psz1[len] = '\0';
        s = -1;
    }
    if(psz1[0]=='N') s=0; /* NaN */
    e = VpExponent10(vp);
    obj  = rb_ary_new2(4);
    rb_ary_push(obj, INT2FIX(s));
    rb_ary_push(obj, str);
    rb_str_resize(str, strlen(psz1));
    rb_ary_push(obj, INT2FIX(10));
    rb_ary_push(obj, INT2NUM(e));
    return obj;
}
sqrt(n) click to toggle source

Returns the square root of the value.

Result has at least n significant digits.

static VALUE
BigDecimal_sqrt(VALUE self, VALUE nFig)
{
    ENTER(5);
    Real *c, *a;
    size_t mx, n;

    GUARD_OBJ(a,GetVpValue(self,1));
    mx = a->Prec *(VpBaseFig() + 1);

    n = GetPositiveInt(nFig) + VpDblFig() + 1;
    if(mx <= n) mx = n;
    GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
    VpSqrt(c, a);
    return ToValue(c);
}
sub(p1, p2) click to toggle source
static VALUE
BigDecimal_sub2(VALUE self, VALUE b, VALUE n)
{
    ENTER(2);
    Real *cv;
    SIGNED_VALUE mx = GetPositiveInt(n);
    if (mx == 0) return BigDecimal_sub(self, b);
    else {
       size_t pl = VpSetPrecLimit(0);
       VALUE   c = BigDecimal_sub(self,b);
       VpSetPrecLimit(pl);
       GUARD_OBJ(cv,GetVpValue(c,1));
       VpLeftRound(cv,VpGetRoundMode(),mx);
       return ToValue(cv);
    }
}
to_d → bigdecimal click to toggle source

Returns self.

# File ext/bigdecimal/lib/bigdecimal/util.rb, line 79
def to_d
  self
end
to_digits → string click to toggle source

Converts a BigDecimal to a String of the form “nnnnnn.mmm”. This method is deprecated; use #to_s(“F”) instead.

require 'bigdecimal'
require 'bigdecimal/util'

d = BigDecimal.new("3.14")
d.to_digits
# => "3.14"

# File ext/bigdecimal/lib/bigdecimal/util.rb, line 65
def to_digits
  if self.nan? || self.infinite? || self.zero?
    self.to_s
  else
    i       = self.to_i.to_s
    _,f,_,z = self.frac.split
    i + "." + ("0"*(-z)) + f
  end
end
to_f() click to toggle source

Returns a new Float object having approximately the same value as the BigDecimal number. Normal accuracy limits and built-in errors of binary Float arithmetic apply.

static VALUE
BigDecimal_to_f(VALUE self)
{
    ENTER(1);
    Real *p;
    double d;
    SIGNED_VALUE e;
    char *buf;
    volatile VALUE str;

    GUARD_OBJ(p, GetVpValue(self, 1));
    if (VpVtoD(&d, &e, p) != 1)
        return rb_float_new(d);
    if (e > (SIGNED_VALUE)(DBL_MAX_10_EXP+BASE_FIG))
        goto overflow;
    if (e < (SIGNED_VALUE)(DBL_MIN_10_EXP-BASE_FIG))
        goto underflow;

    str = rb_str_new(0, VpNumOfChars(p,"E"));
    buf = RSTRING_PTR(str);
    VpToString(p, buf, 0, 0);
    errno = 0;
    d = strtod(buf, 0);
    if (errno == ERANGE) {
        if (d == 0.0) goto underflow;
        if (fabs(d) >= HUGE_VAL) goto overflow;
    }
    return rb_float_new(d);

overflow:
    VpException(VP_EXCEPTION_OVERFLOW, "BigDecimal to Float conversion", 0);
    if (p->sign >= 0)
        return rb_float_new(VpGetDoublePosInf());
    else
        return rb_float_new(VpGetDoubleNegInf());

underflow:
    VpException(VP_EXCEPTION_UNDERFLOW, "BigDecimal to Float conversion", 0);
    if (p->sign >= 0)
        return rb_float_new(0.0);
    else
        return rb_float_new(-0.0);
}
to_i() click to toggle source

Returns the value as an integer (Fixnum or Bignum).

If the BigNumber is infinity or NaN, raises FloatDomainError.

static VALUE
BigDecimal_to_i(VALUE self)
{
    ENTER(5);
    ssize_t e, nf;
    Real *p;

    GUARD_OBJ(p,GetVpValue(self,1));
    BigDecimal_check_num(p);

    e = VpExponent10(p);
    if(e<=0) return INT2FIX(0);
    nf = VpBaseFig();
    if(e<=nf) {
        return LONG2NUM((long)(VpGetSign(p)*(BDIGIT_DBL_SIGNED)p->frac[0]));
    }
    else {
        VALUE a = BigDecimal_split(self);
        VALUE digits = RARRAY_PTR(a)[1];
        VALUE numerator = rb_funcall(digits, rb_intern("to_i"), 0);
        VALUE ret;
        ssize_t dpower = e - (ssize_t)RSTRING_LEN(digits);

        if (VpGetSign(p) < 0) {
            numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1));
        }
        if (dpower < 0) {
            ret = rb_funcall(numerator, rb_intern("div"), 1,
                              rb_funcall(INT2FIX(10), rb_intern("**"), 1,
                                         INT2FIX(-dpower)));
        }
        else
            ret = rb_funcall(numerator, '*', 1,
                             rb_funcall(INT2FIX(10), rb_intern("**"), 1,
                                        INT2FIX(dpower)));
        if (RB_TYPE_P(ret, T_FLOAT))
            rb_raise(rb_eFloatDomainError, "Infinity");
        return ret;
    }
}
to_int() click to toggle source

Returns the value as an integer (Fixnum or Bignum).

If the BigNumber is infinity or NaN, raises FloatDomainError.

static VALUE
BigDecimal_to_i(VALUE self)
{
    ENTER(5);
    ssize_t e, nf;
    Real *p;

    GUARD_OBJ(p,GetVpValue(self,1));
    BigDecimal_check_num(p);

    e = VpExponent10(p);
    if(e<=0) return INT2FIX(0);
    nf = VpBaseFig();
    if(e<=nf) {
        return LONG2NUM((long)(VpGetSign(p)*(BDIGIT_DBL_SIGNED)p->frac[0]));
    }
    else {
        VALUE a = BigDecimal_split(self);
        VALUE digits = RARRAY_PTR(a)[1];
        VALUE numerator = rb_funcall(digits, rb_intern("to_i"), 0);
        VALUE ret;
        ssize_t dpower = e - (ssize_t)RSTRING_LEN(digits);

        if (VpGetSign(p) < 0) {
            numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1));
        }
        if (dpower < 0) {
            ret = rb_funcall(numerator, rb_intern("div"), 1,
                              rb_funcall(INT2FIX(10), rb_intern("**"), 1,
                                         INT2FIX(-dpower)));
        }
        else
            ret = rb_funcall(numerator, '*', 1,
                             rb_funcall(INT2FIX(10), rb_intern("**"), 1,
                                        INT2FIX(dpower)));
        if (RB_TYPE_P(ret, T_FLOAT))
            rb_raise(rb_eFloatDomainError, "Infinity");
        return ret;
    }
}
to_json(*) click to toggle source

return the JSON value

# File ext/json/lib/json/add/bigdecimal.rb, line 25
def to_json(*)
  as_json.to_json
end
to_r() click to toggle source

Converts a BigDecimal to a Rational.

static VALUE
BigDecimal_to_r(VALUE self)
{
    Real *p;
    ssize_t sign, power, denomi_power;
    VALUE a, digits, numerator;

    p = GetVpValue(self,1);
    BigDecimal_check_num(p);

    sign = VpGetSign(p);
    power = VpExponent10(p);
    a = BigDecimal_split(self);
    digits = RARRAY_PTR(a)[1];
    denomi_power = power - RSTRING_LEN(digits);
    numerator = rb_funcall(digits, rb_intern("to_i"), 0);

    if (sign < 0) {
        numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1));
    }
    if (denomi_power < 0) {
        return rb_Rational(numerator,
                           rb_funcall(INT2FIX(10), rb_intern("**"), 1,
                                      INT2FIX(-denomi_power)));
    }
    else {
        return rb_Rational1(rb_funcall(numerator, '*', 1,
                                       rb_funcall(INT2FIX(10), rb_intern("**"), 1,
                                                  INT2FIX(denomi_power))));
    }
}
to_s(s) click to toggle source

Converts the value to a string.

The default format looks like 0.xxxxEnn.

The optional parameter s consists of either an integer; or an optional '+' or ' ', followed by an optional number, followed by an optional 'E' or 'F'.

If there is a '+' at the start of s, positive values are returned with a leading '+'.

A space at the start of s returns positive values with a leading space.

If s contains a number, a space is inserted after each group of that many fractional digits.

If s ends with an 'E', engineering notation (0.xxxxEnn) is used.

If s ends with an 'F', conventional floating point notation is used.

Examples:

BigDecimal.new('-123.45678901234567890').to_s('5F')
    #=> '-123.45678 90123 45678 9'

BigDecimal.new('123.45678901234567890').to_s('+8F')
    #=> '+123.45678901 23456789'

BigDecimal.new('123.45678901234567890').to_s(' F')
    #=> ' 123.4567890123456789'

static VALUE
BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
{
    ENTER(5);
    int   fmt = 0;   /* 0:E format */
    int   fPlus = 0; /* =0:default,=1: set ' ' before digits ,set '+' before digits. */
    Real  *vp;
    volatile VALUE str;
    char  *psz;
    char   ch;
    size_t nc, mc = 0;
    VALUE  f;

    GUARD_OBJ(vp,GetVpValue(self,1));

    if (rb_scan_args(argc,argv,"01",&f)==1) {
        if (RB_TYPE_P(f, T_STRING)) {
            SafeStringValue(f);
            psz = RSTRING_PTR(f);
            if (*psz == ' ') {
                fPlus = 1;
                psz++;
            }
            else if (*psz == '+') {
                fPlus = 2;
                psz++;
            }
            while ((ch = *psz++) != 0) {
                if (ISSPACE(ch)) {
                    continue;
                }
                if (!ISDIGIT(ch)) {
                    if (ch == 'F' || ch == 'f') {
                        fmt = 1; /* F format */
                    }
                    break;
                }
                mc = mc * 10 + ch - '0';
            }
        }
        else {
            mc = (size_t)GetPositiveInt(f);
        }
    }
    if (fmt) {
        nc = VpNumOfChars(vp, "F");
    }
    else {
        nc = VpNumOfChars(vp, "E");
    }
    if (mc > 0) {
        nc += (nc + mc - 1) / mc + 1;
    }

    str = rb_str_new(0, nc);
    psz = RSTRING_PTR(str);

    if (fmt) {
        VpToFString(vp, psz, mc, fPlus);
    }
    else {
        VpToString (vp, psz, mc, fPlus);
    }
    rb_str_resize(str, strlen(psz));
    return str;
}
truncate(n) click to toggle source

Truncate to the nearest 1, returning the result as a BigDecimal.

BigDecimal('3.14159').truncate #=> 3
BigDecimal('8.7').truncate #=> 8

If n is specified and positive, the fractional part of the result has no more than that many digits.

If n is specified and negative, at least that many digits to the left of the decimal point will be 0 in the result.

BigDecimal('3.14159').truncate(3) #=> 3.141
BigDecimal('13345.234').truncate(-2) #=> 13300.0

static VALUE
BigDecimal_truncate(int argc, VALUE *argv, VALUE self)
{
    ENTER(5);
    Real *c, *a;
    int iLoc;
    VALUE vLoc;
    size_t mx, pl = VpSetPrecLimit(0);

    if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
        iLoc = 0;
    } else {
        Check_Type(vLoc, T_FIXNUM);
        iLoc = FIX2INT(vLoc);
    }

    GUARD_OBJ(a,GetVpValue(self,1));
    mx = a->Prec *(VpBaseFig() + 1);
    GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
    VpSetPrecLimit(pl);
    VpActiveRound(c,a,VP_ROUND_DOWN,iLoc); /* 0: truncate */
    if (argc == 0) {
        return BigDecimal_to_i(ToValue(c));
    }
    return ToValue(c);
}
zero?() click to toggle source

Returns True if the value is zero.

static VALUE
BigDecimal_zero(VALUE self)
{
    Real *a = GetVpValue(self,1);
    return VpIsZero(a) ? Qtrue : Qfalse;
}


module BigMath - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module BigMath

Class and method registration

Provides mathematical functions.

Example:

require "bigdecimal"
require "bigdecimal/math"

include BigMath

a = BigDecimal((PI(100)/2).to_s)
puts sin(a,100) # -> 0.10000000000000000000......E1

In Files

  • ext/bigdecimal/bigdecimal.c
  • ext/bigdecimal/lib/bigdecimal/math.rb

Public Class Methods

exp(x, prec) click to toggle source

Computes the value of e (the base of natural logarithms) raised to the power of x, to the specified number of digits of precision.

If x is infinity, returns Infinity.

If x is NaN, returns NaN.

static VALUE
BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
{
    ssize_t prec, n, i;
    Real* vx = NULL;
    VALUE one, d, x1, y, z;
    int negative = 0;
    int infinite = 0;
    int nan = 0;
    double flo;

    prec = NUM2SSIZET(vprec);
    if (prec <= 0) {
        rb_raise(rb_eArgError, "Zero or negative precision for exp");
    }

    /* TODO: the following switch statement is almostly the same as one in the
     *       BigDecimalCmp function. */
    switch (TYPE(x)) {
      case T_DATA:
          if (!is_kind_of_BigDecimal(x)) break;
          vx = DATA_PTR(x);
          negative = VpGetSign(vx) < 0;
          infinite = VpIsPosInf(vx) || VpIsNegInf(vx);
          nan = VpIsNaN(vx);
          break;

      case T_FIXNUM:
          /* fall through */
      case T_BIGNUM:
          vx = GetVpValue(x, 0);
          break;

      case T_FLOAT:
        flo = RFLOAT_VALUE(x);
        negative = flo < 0;
        infinite = isinf(flo);
        nan = isnan(flo);
        if (!infinite && !nan) {
            vx = GetVpValueWithPrec(x, DBL_DIG+1, 0);
        }
        break;

      case T_RATIONAL:
        vx = GetVpValueWithPrec(x, prec, 0);
        break;

      default:
        break;
    }
    if (infinite) {
        if (negative) {
            return ToValue(GetVpValueWithPrec(INT2NUM(0), prec, 1));
        }
        else {
            Real* vy;
            vy = VpCreateRbObject(prec, "#0");
            RB_GC_GUARD(vy->obj);
            VpSetInf(vy, VP_SIGN_POSITIVE_INFINITE);
            return ToValue(vy);
        }
    }
    else if (nan) {
        Real* vy;
        vy = VpCreateRbObject(prec, "#0");
        RB_GC_GUARD(vy->obj);
        VpSetNaN(vy);
        return ToValue(vy);
    }
    else if (vx == NULL) {
        cannot_be_coerced_into_BigDecimal(rb_eArgError, x);
    }
    x = RB_GC_GUARD(vx->obj);

    n = prec + rmpd_double_figures();
    negative = VpGetSign(vx) < 0;
    if (negative) {
        VpSetSign(vx, 1);
    }

    RB_GC_GUARD(one) = ToValue(VpCreateRbObject(1, "1"));
    RB_GC_GUARD(x1) = one;
    RB_GC_GUARD(y)  = one;
    RB_GC_GUARD(d)  = y;
    RB_GC_GUARD(z)  = one;
    i  = 0;

    while (!VpIsZero((Real*)DATA_PTR(d))) {
        VALUE argv[2];
        SIGNED_VALUE const ey = VpExponent10(DATA_PTR(y));
        SIGNED_VALUE const ed = VpExponent10(DATA_PTR(d));
        ssize_t m = n - vabs(ey - ed);
        if (m <= 0) {
            break;
        }
        else if ((size_t)m < rmpd_double_figures()) {
            m = rmpd_double_figures();
        }

        x1 = BigDecimal_mult2(x1, x, SSIZET2NUM(n));
        ++i;
        z = BigDecimal_mult(z, SSIZET2NUM(i));
        argv[0] = z;
        argv[1] = SSIZET2NUM(m);
        d = BigDecimal_div2(2, argv, x1);
        y = BigDecimal_add(y, d);
    }

    if (negative) {
        VALUE argv[2];
        argv[0] = y;
        argv[1] = vprec;
        return BigDecimal_div2(2, argv, one);
    }
    else {
        vprec = SSIZET2NUM(prec - VpExponent10(DATA_PTR(y)));
        return BigDecimal_round(1, &vprec, y);
    }
}
log(x, prec) click to toggle source

Computes the natural logarithm of x to the specified number of digits of precision.

If x is zero or negative, raises Math::DomainError.

If x is positive infinity, returns Infinity.

If x is NaN, returns NaN.

static VALUE
BigMath_s_log(VALUE klass, VALUE x, VALUE vprec)
{
    ssize_t prec, n, i;
    SIGNED_VALUE expo;
    Real* vx = NULL;
    VALUE argv[2], vn, one, two, w, x2, y, d;
    int zero = 0;
    int negative = 0;
    int infinite = 0;
    int nan = 0;
    double flo;
    long fix;

    if (!is_integer(vprec)) {
        rb_raise(rb_eArgError, "precision must be an Integer");
    }

    prec = NUM2SSIZET(vprec);
    if (prec <= 0) {
        rb_raise(rb_eArgError, "Zero or negative precision for exp");
    }

    /* TODO: the following switch statement is almostly the same as one in the
     *       BigDecimalCmp function. */
    switch (TYPE(x)) {
      case T_DATA:
          if (!is_kind_of_BigDecimal(x)) break;
          vx = DATA_PTR(x);
          zero = VpIsZero(vx);
          negative = VpGetSign(vx) < 0;
          infinite = VpIsPosInf(vx) || VpIsNegInf(vx);
          nan = VpIsNaN(vx);
          break;

      case T_FIXNUM:
        fix = FIX2LONG(x);
        zero = fix == 0;
        negative = fix < 0;
        goto get_vp_value;

      case T_BIGNUM:
        zero = RBIGNUM_ZERO_P(x);
        negative = RBIGNUM_NEGATIVE_P(x);
get_vp_value:
        if (zero || negative) break;
        vx = GetVpValue(x, 0);
        break;

      case T_FLOAT:
        flo = RFLOAT_VALUE(x);
        zero = flo == 0;
        negative = flo < 0;
        infinite = isinf(flo);
        nan = isnan(flo);
        if (!zero && !negative && !infinite && !nan) {
            vx = GetVpValueWithPrec(x, DBL_DIG+1, 1);
        }
        break;

      case T_RATIONAL:
        zero = RRATIONAL_ZERO_P(x);
        negative = RRATIONAL_NEGATIVE_P(x);
        if (zero || negative) break;
        vx = GetVpValueWithPrec(x, prec, 1);
        break;

      case T_COMPLEX:
        rb_raise(rb_eMathDomainError,
                 "Complex argument for BigMath.log");

      default:
        break;
    }
    if (infinite && !negative) {
        Real* vy;
        vy = VpCreateRbObject(prec, "#0");
        RB_GC_GUARD(vy->obj);
        VpSetInf(vy, VP_SIGN_POSITIVE_INFINITE);
        return ToValue(vy);
    }
    else if (nan) {
        Real* vy;
        vy = VpCreateRbObject(prec, "#0");
        RB_GC_GUARD(vy->obj);
        VpSetNaN(vy);
        return ToValue(vy);
    }
    else if (zero || negative) {
        rb_raise(rb_eMathDomainError,
                 "Zero or negative argument for log");
    }
    else if (vx == NULL) {
        cannot_be_coerced_into_BigDecimal(rb_eArgError, x);
    }
    x = ToValue(vx);

    RB_GC_GUARD(one) = ToValue(VpCreateRbObject(1, "1"));
    RB_GC_GUARD(two) = ToValue(VpCreateRbObject(1, "2"));

    n = prec + rmpd_double_figures();
    RB_GC_GUARD(vn) = SSIZET2NUM(n);
    expo = VpExponent10(vx);
    if (expo < 0 || expo >= 3) {
        char buf[16];
        snprintf(buf, 16, "1E%"PRIdVALUE, -expo);
        x = BigDecimal_mult2(x, ToValue(VpCreateRbObject(1, buf)), vn);
    }
    else {
        expo = 0;
    }
    w = BigDecimal_sub(x, one);
    argv[0] = BigDecimal_add(x, one);
    argv[1] = vn;
    x = BigDecimal_div2(2, argv, w);
    RB_GC_GUARD(x2) = BigDecimal_mult2(x, x, vn);
    RB_GC_GUARD(y)  = x;
    RB_GC_GUARD(d)  = y;
    i = 1;
    while (!VpIsZero((Real*)DATA_PTR(d))) {
        SIGNED_VALUE const ey = VpExponent10(DATA_PTR(y));
        SIGNED_VALUE const ed = VpExponent10(DATA_PTR(d));
        ssize_t m = n - vabs(ey - ed);
        if (m <= 0) {
            break;
        }
        else if ((size_t)m < rmpd_double_figures()) {
            m = rmpd_double_figures();
        }

        x = BigDecimal_mult2(x2, x, vn);
        i += 2;
        argv[0] = SSIZET2NUM(i);
        argv[1] = SSIZET2NUM(m);
        d = BigDecimal_div2(2, argv, x);
        y = BigDecimal_add(y, d);
    }

    y = BigDecimal_mult(y, two);
    if (expo != 0) {
        VALUE log10, vexpo, dy;
        log10 = BigMath_s_log(klass, INT2FIX(10), vprec);
        vexpo = ToValue(GetVpValue(SSIZET2NUM(expo), 1));
        dy = BigDecimal_mult(log10, vexpo);
        y = BigDecimal_add(y, dy);
    }

    return y;
}

Public Instance Methods

E(prec) click to toggle source

Computes e (the base of natural logarithms) to the specified number of digits of precision.

# File ext/bigdecimal/lib/bigdecimal/math.rb, line 188
def E(prec)
  raise ArgumentError, "Zero or negative precision for E" if prec <= 0
  n    = prec + BigDecimal.double_fig
  one  = BigDecimal("1")
  y  = one
  d  = y
  z  = one
  i  = 0
  while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
    m = BigDecimal.double_fig if m < BigDecimal.double_fig
    i += 1
    z *= i
    d  = one.div(z,m)
    y += d
  end
  y
end
PI(prec) click to toggle source

Computes the value of pi to the specified number of digits of precision.

# File ext/bigdecimal/lib/bigdecimal/math.rb, line 148
def PI(prec)
  raise ArgumentError, "Zero or negative argument for PI" if prec <= 0
  n      = prec + BigDecimal.double_fig
  zero   = BigDecimal("0")
  one    = BigDecimal("1")
  two    = BigDecimal("2")

  m25    = BigDecimal("-0.04")
  m57121 = BigDecimal("-57121")

  pi     = zero

  d = one
  k = one
  w = one
  t = BigDecimal("-80")
  while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
    m = BigDecimal.double_fig if m < BigDecimal.double_fig
    t   = t*m25
    d   = t.div(k,m)
    k   = k+two
    pi  = pi + d
  end

  d = one
  k = one
  w = one
  t = BigDecimal("956")
  while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
    m = BigDecimal.double_fig if m < BigDecimal.double_fig
    t   = t.div(m57121,n)
    d   = t.div(k,m)
    pi  = pi + d
    k   = k+two
  end
  pi
end
atan(x, prec) click to toggle source

Computes the arctangent of x to the specified number of digits of precision.

If x is NaN, returns NaN.

# File ext/bigdecimal/lib/bigdecimal/math.rb, line 119
def atan(x, prec)
  raise ArgumentError, "Zero or negative precision for atan" if prec <= 0
  return BigDecimal("NaN") if x.nan?
  pi = PI(prec)
  x = -x if neg = x < 0
  return pi.div(neg ? -2 : 2, prec) if x.infinite?
  return pi / (neg ? -4 : 4) if x.round(prec) == 1
  x = BigDecimal("1").div(x, prec) if inv = x > 1
  x = (-1 + sqrt(1 + x**2, prec))/x if dbl = x > 0.5
  n    = prec + BigDecimal.double_fig
  y = x
  d = y
  t = x
  r = BigDecimal("3")
  x2 = x.mult(x,n)
  while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
    m = BigDecimal.double_fig if m < BigDecimal.double_fig
    t = -t.mult(x2,n)
    d = t.div(r,m)
    y += d
    r += 2
  end
  y *= 2 if dbl
  y = pi / 2 - y if inv
  y = -y if neg
  y
end
cos(x, prec) click to toggle source

Computes the cosine of x to the specified number of digits of precision.

If x is infinite or NaN, returns NaN.

# File ext/bigdecimal/lib/bigdecimal/math.rb, line 83
def cos(x, prec)
  raise ArgumentError, "Zero or negative precision for cos" if prec <= 0
  return BigDecimal("NaN") if x.infinite? || x.nan?
  n    = prec + BigDecimal.double_fig
  one  = BigDecimal("1")
  two  = BigDecimal("2")
  x = -x if x < 0
  if x > (twopi = two * BigMath.PI(prec))
    if x > 30
      x = twopi
    else
      x -= twopi while x > twopi
    end
  end
  x1 = one
  x2 = x.mult(x,n)
  sign = 1
  y = one
  d = y
  i = BigDecimal("0")
  z = one
  while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
    m = BigDecimal.double_fig if m < BigDecimal.double_fig
    sign = -sign
    x1  = x2.mult(x1,n)
    i  += two
    z  *= (i-one) * i
    d   = sign * x1.div(z,m)
    y  += d
  end
  y
end
sin(x, prec) click to toggle source

Computes the sine of x to the specified number of digits of precision.

If x is infinite or NaN, returns NaN.

# File ext/bigdecimal/lib/bigdecimal/math.rb, line 47
def sin(x, prec)
  raise ArgumentError, "Zero or negative precision for sin" if prec <= 0
  return BigDecimal("NaN") if x.infinite? || x.nan?
  n    = prec + BigDecimal.double_fig
  one  = BigDecimal("1")
  two  = BigDecimal("2")
  x = -x if neg = x < 0
  if x > (twopi = two * BigMath.PI(prec))
    if x > 30
      x = twopi
    else
      x -= twopi while x > twopi
    end
  end
  x1   = x
  x2   = x.mult(x,n)
  sign = 1
  y    = x
  d    = y
  i    = one
  z    = one
  while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
    m = BigDecimal.double_fig if m < BigDecimal.double_fig
    sign = -sign
    x1  = x2.mult(x1,n)
    i  += two
    z  *= (i-one) * i
    d   = sign * x1.div(z,m)
    y  += d
  end
  neg ? -y : y
end
sqrt(x,prec) click to toggle source

Computes the square root of x to the specified number of digits of precision.

BigDecimal.new('2').sqrt(16).to_s

-> "0.14142135623730950488016887242096975E1"
# File ext/bigdecimal/lib/bigdecimal/math.rb, line 40
def sqrt(x,prec)
  x.sqrt(prec)
end


class Bignum - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Bignum

When mathn is required Bignum's division and exponentiation are enhanced to return more precise values from mathematical expressions.

In Files

  • lib/mathn.rb
  • lib/rational.rb

Parent

Object

Public Instance Methods

**(other) click to toggle source

Exponentiate by other

# File lib/mathn.rb, line 107
def ** (other)
  if self < 0 && other.round != other
    Complex(self, 0.0) ** other
  else
    power!(other)
  end
end
Also aliased as: power!
power!(other) click to toggle source
Alias for: **


class CGI - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CGI

Overview

The Common Gateway Interface (CGI) is a simple protocol for passing an HTTP request from a web server to a standalone program, and returning the output to the web browser. Basically, a CGI program is called with the parameters of the request passed in either in the environment (GET) or via $stdin (POST), and everything it prints to $stdout is returned to the client.

This file holds the CGI class. This class provides functionality for retrieving HTTP request parameters, managing cookies, and generating HTML output.

The file CGI::Session provides session management functionality; see that class for more details.

See www.w3.org/CGI/ for more information on the CGI protocol.

Introduction

CGI is a large class, providing several categories of methods, many of which are mixed in from other modules. Some of the documentation is in this class, some in the modules CGI::QueryExtension and CGI::HtmlExtension. See CGI::Cookie for specific information on handling cookies, and cgi/session.rb (CGI::Session) for information on sessions.

For queries, CGI provides methods to get at environmental variables, parameters, cookies, and multipart request data. For responses, CGI provides methods for writing output and generating HTML.

Read on for more details. Examples are provided at the bottom.

Queries

The CGI class dynamically mixes in parameter and cookie-parsing functionality, environmental variable access, and support for parsing multipart requests (including uploaded files) from the CGI::QueryExtension module.

Environmental Variables

The standard CGI environmental variables are available as read-only attributes of a CGI object. The following is a list of these variables:

AUTH_TYPE               HTTP_HOST          REMOTE_IDENT
CONTENT_LENGTH          HTTP_NEGOTIATE     REMOTE_USER
CONTENT_TYPE            HTTP_PRAGMA        REQUEST_METHOD
GATEWAY_INTERFACE       HTTP_REFERER       SCRIPT_NAME
HTTP_ACCEPT             HTTP_USER_AGENT    SERVER_NAME
HTTP_ACCEPT_CHARSET     PATH_INFO          SERVER_PORT
HTTP_ACCEPT_ENCODING    PATH_TRANSLATED    SERVER_PROTOCOL
HTTP_ACCEPT_LANGUAGE    QUERY_STRING       SERVER_SOFTWARE
HTTP_CACHE_CONTROL      REMOTE_ADDR
HTTP_FROM               REMOTE_HOST

For each of these variables, there is a corresponding attribute with the same name, except all lower case and without a preceding HTTP_. content_length and server_port are integers; the rest are strings.

Parameters

The method params() returns a hash of all parameters in the request as name/value-list pairs, where the value-list is an Array of one or more values. The CGI object itself also behaves as a hash of parameter names to values, but only returns a single value (as a String) for each parameter name.

For instance, suppose the request contains the parameter “favourite_colours” with the multiple values “blue” and “green”. The following behaviour would occur:

cgi.params["favourite_colours"]  # => ["blue", "green"]
cgi["favourite_colours"]         # => "blue"

If a parameter does not exist, the former method will return an empty array, the latter an empty string. The simplest way to test for existence of a parameter is by the has_key? method.

Cookies

HTTP Cookies are automatically parsed from the request. They are available from the cookies() accessor, which returns a hash from cookie name to CGI::Cookie object.

Multipart requests

If a request's method is POST and its content type is multipart/form-data, then it may contain uploaded files. These are stored by the QueryExtension module in the parameters of the request. The parameter name is the name attribute of the file input field, as usual. However, the value is not a string, but an IO object, either an IOString for small files, or a Tempfile for larger ones. This object also has the additional singleton methods:

local_path()

the path of the uploaded file on the local filesystem

original_filename()

the name of the file on the client computer

content_type()

the content type of the file

Responses

The CGI class provides methods for sending header and content output to the HTTP client, and mixes in methods for programmatic HTML generation from CGI::HtmlExtension and CGI::TagMaker modules. The precise version of HTML to use for HTML generation is specified at object creation time.

Writing output

The simplest way to send output to the HTTP client is using the out() method. This takes the HTTP headers as a hash parameter, and the body content via a block. The headers can be generated as a string using the http_header() method. The output stream can be written directly to using the print() method.

Generating HTML

Each HTML element has a corresponding method for generating that element as a String. The name of this method is the same as that of the element, all lowercase. The attributes of the element are passed in as a hash, and the body as a no-argument block that evaluates to a String. The HTML generation module knows which elements are always empty, and silently drops any passed-in body. It also knows which elements require matching closing tags and which don't. However, it does not know what attributes are legal for which elements.

There are also some additional HTML generation methods mixed in from the CGI::HtmlExtension module. These include individual methods for the different types of form inputs, and methods for elements that commonly take particular attributes where the attributes can be directly specified as arguments, rather than via a hash.

Examples of use

Get form values

require "cgi"
cgi = CGI.new
value = cgi['field_name']   # <== value string for 'field_name'
  # if not 'field_name' included, then return "".
fields = cgi.keys            # <== array of field names

# returns true if form has 'field_name'
cgi.has_key?('field_name')
cgi.has_key?('field_name')
cgi.include?('field_name')

CAUTION! cgi returned an Array with the old cgi.rb(included in ruby 1.6)

Get form values as hash

require "cgi"
cgi = CGI.new
params = cgi.params

cgi.params is a hash.

cgi.params['new_field_name'] = ["value"]  # add new param
cgi.params['field_name'] = ["new_value"]  # change value
cgi.params.delete('field_name')           # delete param
cgi.params.clear                          # delete all params

Save form values to file

require "pstore"
db = PStore.new("query.db")
db.transaction do
  db["params"] = cgi.params
end

Restore form values from file

require "pstore"
db = PStore.new("query.db")
db.transaction do
  cgi.params = db["params"]
end

Get multipart form values

require "cgi"
cgi = CGI.new
value = cgi['field_name']   # <== value string for 'field_name'
value.read                  # <== body of value
value.local_path            # <== path to local file of value
value.original_filename     # <== original filename of value
value.content_type          # <== content_type of value

and value has StringIO or Tempfile class methods.

Get cookie values

require "cgi"
cgi = CGI.new
values = cgi.cookies['name']  # <== array of 'name'
  # if not 'name' included, then return [].
names = cgi.cookies.keys      # <== array of cookie names

and cgi.cookies is a hash.

Get cookie objects

require "cgi"
cgi = CGI.new
for name, cookie in cgi.cookies
  cookie.expires = Time.now + 30
end
cgi.out("cookie" => cgi.cookies) {"string"}

cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... }

require "cgi"
cgi = CGI.new
cgi.cookies['name'].expires = Time.now + 30
cgi.out("cookie" => cgi.cookies['name']) {"string"}

Print http header and html string to $DEFAULT_OUTPUT ($>)

require "cgi"
cgi = CGI.new("html4")  # add HTML generation methods
cgi.out do
  cgi.html do
    cgi.head do
      cgi.title { "TITLE" }
    end +
    cgi.body do
      cgi.form("ACTION" => "uri") do
        cgi.p do
          cgi.textarea("get_text") +
          cgi.br +
          cgi.submit
        end
      end +
      cgi.pre do
        CGI::escapeHTML(
          "params: #{cgi.params.inspect}\n" +
          "cookies: #{cgi.cookies.inspect}\n" +
          ENV.collect do |key, value|
            "#{key} --> #{value}\n"
          end.join("")
        )
      end
    end
  end
end

# add HTML generation methods
CGI.new("html3")    # html3.2
CGI.new("html4")    # html4.01 (Strict)
CGI.new("html4Tr")  # html4.01 Transitional
CGI.new("html4Fr")  # html4.01 Frameset
CGI.new("html5")    # html5

In Files

  • lib/cgi/cookie.rb
  • lib/cgi/core.rb
  • lib/cgi/html.rb
  • lib/cgi/session/pstore.rb
  • lib/cgi/session.rb
  • lib/cgi/util.rb
  • lib/cgi.rb

Parent

Object

Constants

CR

String for carriage return

EOL

Standard internet newline sequence

HTTP_STATUS

HTTP status codes.

LF

String for linefeed

MAX_MULTIPART_COUNT

Maximum number of request parameters when multipart

MAX_MULTIPART_LENGTH

Maximum content length of multipart data

NEEDS_BINMODE

Whether processing will be required in binary vs text

PATH_SEPARATOR

Path separators in different environments.

RFC822_DAYS

Abbreviated day-of-week names specified by RFC 822

RFC822_MONTHS

Abbreviated month names specified by RFC 822

TABLE_FOR_ESCAPE_HTML__

The set of special characters and their escaped values

Attributes

accept_charset[R]

Return the accept character set for this CGI instance.

Public Class Methods

accept_charset() click to toggle source

Return the accept character set for all new CGI instances.

# File lib/cgi/core.rb, line 742
def self.accept_charset
  @@accept_charset
end
accept_charset=(accept_charset) click to toggle source

Set the accept character set for all new CGI instances.

# File lib/cgi/core.rb, line 747
def self.accept_charset=(accept_charset)
  @@accept_charset=accept_charset
end
escape(string) click to toggle source

URL-encode a string.

url_encoded_string = CGI::escape("'Stop!' said Fred")
   # => "%27Stop%21%27+said+Fred"

# File lib/cgi/util.rb, line 6
def CGI::escape(string)
  encoding = string.encoding
  string.dup.force_encoding('ASCII-8BIT').gsub(/([^ a-zA-Z0-9_.-]+)/) do
    '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
  end.tr(' ', '+').force_encoding(encoding)
end
escapeElement(string, *elements) click to toggle source

Escape only the tags of certain HTML elements in string.

Takes an element or elements or array of elements. Each element is specified by the name of the element, without angle brackets. This matches both the start and the end tag of that element. The attribute list of the open tag will also be escaped (for instance, the double-quotes surrounding attribute values).

print CGI::escapeElement('<BR><A HREF="url"></A>', "A", "IMG")
  # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"

print CGI::escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
  # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
# File lib/cgi/util.rb, line 113
def CGI::escapeElement(string, *elements)
  elements = elements[0] if elements[0].kind_of?(Array)
  unless elements.empty?
    string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/) do
      CGI::escapeHTML($&)
    end
  else
    string
  end
end
escapeHTML(string) click to toggle source

Escape special characters in HTML, namely &"<>

CGI::escapeHTML('Usage: foo "bar" <baz>')
   # => "Usage: foo &quot;bar&quot; &lt;baz&gt;"

# File lib/cgi/util.rb, line 35
def CGI::escapeHTML(string)
  string.gsub(/['&\"<>]/, TABLE_FOR_ESCAPE_HTML__)
end
escape_element(str) click to toggle source

Synonym for ::escapeElement

# File lib/cgi/util.rb, line 145
def CGI::escape_element(str)
  escapeElement(str)
end
escape_html(str) click to toggle source

Synonym for ::escapeHTML

# File lib/cgi/util.rb, line 91
def CGI::escape_html(str)
  escapeHTML(str)
end
new(tag_maker) { block } click to toggle source
new(options_hash = {}) { block }

Create a new CGI instance.

tag_maker

This is the same as using the options_hash form with the value { :tag_maker => tag_maker } Note that it is recommended to use the options_hash form, since it also allows you specify the charset you will accept.

options_hash

A Hash that recognizes two options:

:accept_charset

specifies encoding of received query string. If omitted, @@accept_charset is used. If the encoding is not valid, a CGI::InvalidEncoding will be raised.

Example. Suppose @@accept_charset is “UTF-8”

when not specified:

cgi=CGI.new      # @accept_charset # => "UTF-8"

when specified as “EUC-JP”:

cgi=CGI.new(:accept_charset => "EUC-JP") # => "EUC-JP"
:tag_maker

String that specifies which version of the HTML generation methods to use. If not specified, no HTML generation methods will be loaded.

The following values are supported:

“html3”

HTML 3.x

“html4”

HTML 4.0

“html4Tr”

HTML 4.0 Transitional

“html4Fr”

HTML 4.0 with Framesets

“html5”

HTML 5

block

If provided, the block is called when an invalid encoding is encountered. For example:

encoding_errors={}
cgi=CGI.new(:accept_charset=>"EUC-JP") do |name,value|
  encoding_errors[name] = value
end

Finally, if the CGI object is not created in a standard CGI call environment (that is, it can't locate REQUEST_METHOD in its environment), then it will run in “offline” mode. In this mode, it reads its parameters from the command line or (failing that) from standard input. Otherwise, cookies and other parameters are parsed automatically from the standard CGI locations, which varies according to the REQUEST_METHOD.

# File lib/cgi/core.rb, line 811
def initialize(options = {}, &block) # :yields: name, value
  @accept_charset_error_block = block_given? ? block : nil
  @options={:accept_charset=>@@accept_charset}
  case options
  when Hash
    @options.merge!(options)
  when String
    @options[:tag_maker]=options
  end
  @accept_charset=@options[:accept_charset]
  if defined?(MOD_RUBY) && !ENV.key?("GATEWAY_INTERFACE")
    Apache.request.setup_cgi_env
  end

  extend QueryExtension
  @multipart = false

  initialize_query()  # set @params, @cookies
  @output_cookies = nil
  @output_hidden = nil

  case @options[:tag_maker]
  when "html3"
    require 'cgi/html'
    extend Html3
    element_init()
    extend HtmlExtension
  when "html4"
    require 'cgi/html'
    extend Html4
    element_init()
    extend HtmlExtension
  when "html4Tr"
    require 'cgi/html'
    extend Html4Tr
    element_init()
    extend HtmlExtension
  when "html4Fr"
    require 'cgi/html'
    extend Html4Tr
    element_init()
    extend Html4Fr
    element_init()
    extend HtmlExtension
  when "html5"
    require 'cgi/html'
    extend Html5
    element_init()
    extend HtmlExtension
  end
end
parse(query) click to toggle source

Parse an HTTP query string into a hash of key=>value pairs.

params = CGI::parse("query_string")
  # {"name1" => ["value1", "value2", ...],
  #  "name2" => ["value1", "value2", ...], ... }

# File lib/cgi/core.rb, line 374
def CGI::parse(query)
  params = {}
  query.split(/[&;]/).each do |pairs|
    key, value = pairs.split('=',2).collect{|v| CGI::unescape(v) }

    next unless key

    params[key] ||= []
    params[key].push(value) if value
  end

  params.default=[].freeze
  params
end
pretty(string, shift = " ") click to toggle source

Prettify (indent) an HTML string.

string is the HTML string to indent. shift is the indentation unit to use; it defaults to two spaces.

print CGI::pretty("<HTML><BODY></BODY></HTML>")
  # <HTML>
  #   <BODY>
  #   </BODY>
  # </HTML>

print CGI::pretty("<HTML><BODY></BODY></HTML>", "\t")
  # <HTML>
  #         <BODY>
  #         </BODY>
  # </HTML>
# File lib/cgi/util.rb, line 188
def CGI::pretty(string, shift = "  ")
  lines = string.gsub(/(?!\A)<.*?>/, "\n\\0").gsub(/<.*?>(?!\n)/, "\\0\n")
  end_pos = 0
  while end_pos = lines.index(/^<\/(\w+)/, end_pos)
    element = $1.dup
    start_pos = lines.rindex(/^\s*<#{element}/, end_pos)
    lines[start_pos ... end_pos] = "__" + lines[start_pos ... end_pos].gsub(/\n(?!\z)/, "\n" + shift) + "__"
  end
  lines.gsub(/^((?:#{Regexp::quote(shift)})*)__(?=<\/?\w)/, '\1')
end
rfc1123_date(time) click to toggle source

Format a Time object as a String using the format specified by RFC 1123.

CGI::rfc1123_date(Time.now)
  # Sat, 01 Jan 2000 00:00:00 GMT
# File lib/cgi/util.rb, line 164
def CGI::rfc1123_date(time)
  t = time.clone.gmtime
  return format("%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
              RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year,
              t.hour, t.min, t.sec)
end
unescape(string,encoding=@@accept_charset) click to toggle source

URL-decode a string with encoding(optional).

string = CGI::unescape("%27Stop%21%27+said+Fred")
   # => "'Stop!' said Fred"

# File lib/cgi/util.rb, line 16
def CGI::unescape(string,encoding=@@accept_charset)
  str=string.tr('+', ' ').force_encoding(Encoding::ASCII_8BIT).gsub(/((?:%[0-9a-fA-F]{2})+)/) do
    [$1.delete('%')].pack('H*')
  end.force_encoding(encoding)
  str.valid_encoding? ? str : str.force_encoding(string.encoding)
end
unescapeElement(string, *elements) click to toggle source

Undo escaping such as that done by ::escapeElement

print CGI::unescapeElement(
        CGI::escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")
  # "&lt;BR&gt;<A HREF="url"></A>"

print CGI::unescapeElement(
        CGI::escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])
  # "&lt;BR&gt;<A HREF="url"></A>"
# File lib/cgi/util.rb, line 133
def CGI::unescapeElement(string, *elements)
  elements = elements[0] if elements[0].kind_of?(Array)
  unless elements.empty?
    string.gsub(/&lt;\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?&gt;/) do
      CGI::unescapeHTML($&)
    end
  else
    string
  end
end
unescapeHTML(string) click to toggle source

Unescape a string that has been HTML-escaped

CGI::unescapeHTML("Usage: foo &quot;bar&quot; &lt;baz&gt;")
   # => "Usage: foo \"bar\" <baz>"

# File lib/cgi/util.rb, line 42
def CGI::unescapeHTML(string)
  enc = string.encoding
  if [Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE].include?(enc)
    return string.gsub(Regexp.new('&(apos|amp|quot|gt|lt|#[0-9]+|#x[0-9A-Fa-f]+);'.encode(enc))) do
      case $1.encode("US-ASCII")
      when 'apos'                then "'".encode(enc)
      when 'amp'                 then '&'.encode(enc)
      when 'quot'                then '"'.encode(enc)
      when 'gt'                  then '>'.encode(enc)
      when 'lt'                  then '<'.encode(enc)
      when /\A#0*(\d+)\z/        then $1.to_i.chr(enc)
      when /\A#x([0-9a-f]+)\z/  then $1.hex.chr(enc)
      end
    end
  end
  asciicompat = Encoding.compatible?(string, "a")
  string.gsub(/&(apos|amp|quot|gt|lt|\#[0-9]+|\#[xX][0-9A-Fa-f]+);/) do
    match = $1.dup
    case match
    when 'apos'                then "'"
    when 'amp'                 then '&'
    when 'quot'                then '"'
    when 'gt'                  then '>'
    when 'lt'                  then '<'
    when /\A#0*(\d+)\z/
      n = $1.to_i
      if enc == Encoding::UTF_8 or
        enc == Encoding::ISO_8859_1 && n < 256 or
        asciicompat && n < 128
        n.chr(enc)
      else
        "&##{$1};"
      end
    when /\A#x([0-9a-f]+)\z/
      n = $1.hex
      if enc == Encoding::UTF_8 or
        enc == Encoding::ISO_8859_1 && n < 256 or
        asciicompat && n < 128
        n.chr(enc)
      else
        "&#x#{$1};"
      end
    else
      "&#{match};"
    end
  end
end
unescape_element(str) click to toggle source

Synonym for ::unescapeElement

# File lib/cgi/util.rb, line 150
def CGI::unescape_element(str)
  unescapeElement(str)
end
unescape_html(str) click to toggle source

Synonym for ::unescapeHTML

# File lib/cgi/util.rb, line 96
def CGI::unescape_html(str)
  unescapeHTML(str)
end

Public Instance Methods

header(options='text/html') click to toggle source

This method is an alias for http_header, when HTML5 tag maker is inactive.

NOTE: use http_header to create HTTP header blocks, this alias is only provided for backwards compatibility.

Using header with the HTML5 tag maker will create a <header> element.

Alias for: http_header
http_header(content_type_string="text/html") click to toggle source
http_header(headers_hash)

Create an HTTP header block as a string.

Includes the empty line that ends the header block.

content_type_string

If this form is used, this string is the Content-Type

headers_hash

A Hash of header values. The following header keys are recognized:

type

The Content-Type header. Defaults to “text/html”

charset

The charset of the body, appended to the Content-Type header.

nph

A boolean value. If true, prepend protocol string and status code, and date; and sets default values for “server” and “connection” if not explicitly set.

status

The HTTP status code as a String, returned as the Status header. The values are:

OK

200 OK

PARTIAL_CONTENT

206 Partial Content

MULTIPLE_CHOICES

300 Multiple Choices

MOVED

301 Moved Permanently

REDIRECT

302 Found

NOT_MODIFIED

304 Not Modified

BAD_REQUEST

400 Bad Request

AUTH_REQUIRED

401 Authorization Required

FORBIDDEN

403 Forbidden

NOT_FOUND

404 Not Found

METHOD_NOT_ALLOWED

405 Method Not Allowed

NOT_ACCEPTABLE

406 Not Acceptable

LENGTH_REQUIRED

411 Length Required

PRECONDITION_FAILED

412 Precondition Failed

SERVER_ERROR

500 Internal Server Error

NOT_IMPLEMENTED

501 Method Not Implemented

BAD_GATEWAY

502 Bad Gateway

VARIANT_ALSO_VARIES

506 Variant Also Negotiates

server

The server software, returned as the Server header.

connection

The connection type, returned as the Connection header (for instance, “close”.

length

The length of the content that will be sent, returned as the Content-Length header.

language

The language of the content, returned as the Content-Language header.

expires

The time on which the current content expires, as a Time object, returned as the Expires header.

cookie

A cookie or cookies, returned as one or more Set-Cookie headers. The value can be the literal string of the cookie; a CGI::Cookie object; an Array of literal cookie strings or Cookie objects; or a hash all of whose values are literal cookie strings or Cookie objects.

These cookies are in addition to the cookies held in the @output_cookies field.

Other headers can also be set; they are appended as key: value.

Examples:

http_header
  # Content-Type: text/html

http_header("text/plain")
  # Content-Type: text/plain

http_header("nph"        => true,
            "status"     => "OK",  # == "200 OK"
              # "status"     => "200 GOOD",
            "server"     => ENV['SERVER_SOFTWARE'],
            "connection" => "close",
            "type"       => "text/html",
            "charset"    => "iso-2022-jp",
              # Content-Type: text/html; charset=iso-2022-jp
            "length"     => 103,
            "language"   => "ja",
            "expires"    => Time.now + 30,
            "cookie"     => [cookie1, cookie2],
            "my_header1" => "my_value"
            "my_header2" => "my_value")

This method does not perform charset conversion.

# File lib/cgi/core.rb, line 152
def http_header(options='text/html')
  if options.is_a?(String)
    content_type = options
    buf = _header_for_string(content_type)
  elsif options.is_a?(Hash)
    if options.size == 1 && options.has_key?('type')
      content_type = options['type']
      buf = _header_for_string(content_type)
    else
      buf = _header_for_hash(options.dup)
    end
  else
    raise ArgumentError.new("expected String or Hash but got #{options.class}")
  end
  if defined?(MOD_RUBY)
    _header_for_modruby(buf)
    return ''
  else
    buf << EOL    # empty line of separator
    return buf
  end
end
Also aliased as: header
out(content_type_string='text/html') click to toggle source
out(headers_hash)

Print an HTTP header and body to $DEFAULT_OUTPUT ($>)

content_type_string

If a string is passed, it is assumed to be the content type.

headers_hash

This is a Hash of headers, similar to that used by http_header.

block

A block is required and should evaluate to the body of the response.

Content-Length is automatically calculated from the size of the String returned by the content block.

If ENV['REQUEST_METHOD'] == "HEAD", then only the header is output (the content block is still required, but it is ignored).

If the charset is “iso-2022-jp” or “euc-jp” or “shift_jis” then the content is converted to this charset, and the language is set to “ja”.

Example:

cgi = CGI.new
cgi.out{ "string" }
  # Content-Type: text/html
  # Content-Length: 6
  #
  # string

cgi.out("text/plain") { "string" }
  # Content-Type: text/plain
  # Content-Length: 6
  #
  # string

cgi.out("nph"        => true,
        "status"     => "OK",  # == "200 OK"
        "server"     => ENV['SERVER_SOFTWARE'],
        "connection" => "close",
        "type"       => "text/html",
        "charset"    => "iso-2022-jp",
          # Content-Type: text/html; charset=iso-2022-jp
        "language"   => "ja",
        "expires"    => Time.now + (3600 * 24 * 30),
        "cookie"     => [cookie1, cookie2],
        "my_header1" => "my_value",
        "my_header2" => "my_value") { "string" }
   # HTTP/1.1 200 OK
   # Date: Sun, 15 May 2011 17:35:54 GMT
   # Server: Apache 2.2.0
   # Connection: close
   # Content-Type: text/html; charset=iso-2022-jp
   # Content-Length: 6
   # Content-Language: ja
   # Expires: Tue, 14 Jun 2011 17:35:54 GMT
   # Set-Cookie: foo
   # Set-Cookie: bar
   # my_header1: my_value
   # my_header2: my_value
   #
   # string

# File lib/cgi/core.rb, line 348
def out(options = "text/html") # :yield:

  options = { "type" => options } if options.kind_of?(String)
  content = yield
  options["length"] = content.bytesize.to_s
  output = stdoutput
  output.binmode if defined? output.binmode
  output.print http_header(options)
  output.print content unless "HEAD" == env_table['REQUEST_METHOD']
end
print(*options) click to toggle source

Print an argument or list of arguments to the default output stream

cgi = CGI.new
cgi.print    # default:  cgi.print == $DEFAULT_OUTPUT.print
# File lib/cgi/core.rb, line 364
def print(*options)
  stdoutput.print(*options)
end


class CGI::Cookie - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CGI::Cookie

Class representing an HTTP cookie.

In addition to its specific fields and methods, a Cookie instance is a delegator to the array of its values.

See RFC 2965.

Examples of use

cookie1 = CGI::Cookie::new("name", "value1", "value2", ...)
cookie1 = CGI::Cookie::new("name" => "name", "value" => "value")
cookie1 = CGI::Cookie::new('name'    => 'name',
                           'value'   => ['value1', 'value2', ...],
                           'path'    => 'path',   # optional
                           'domain'  => 'domain', # optional
                           'expires' => Time.now, # optional
                           'secure'  => true      # optional
                          )

cgi.out("cookie" => [cookie1, cookie2]) { "string" }

name    = cookie1.name
values  = cookie1.value
path    = cookie1.path
domain  = cookie1.domain
expires = cookie1.expires
secure  = cookie1.secure

cookie1.name    = 'name'
cookie1.value   = ['value1', 'value2', ...]
cookie1.path    = 'path'
cookie1.domain  = 'domain'
cookie1.expires = Time.now + 30
cookie1.secure  = true

In Files

  • lib/cgi/cookie.rb

Parent

Array

Attributes

domain[RW]

Domain for which this cookie applies, as a String

expires[RW]

Time at which this cookie expires, as a Time

name[RW]

Name of this cookie, as a String

path[RW]

Path for which this cookie applies, as a String

secure[R]

True if this cookie is secure; false otherwise

Public Class Methods

new(name_string,*value) click to toggle source
new(options_hash)

Create a new CGI::Cookie object.

name_string

The name of the cookie; in this form, there is no domain or expiration. The path is gleaned from the SCRIPT_NAME environment variable, and secure is false.

*value

value or list of values of the cookie

options_hash

A Hash of options to initialize this Cookie. Possible options are:

name

the name of the cookie. Required.

value

the cookie's value or list of values.

path

the path for which this cookie applies. Defaults to the the value of the SCRIPT_NAME environment variable.

domain

the domain for which this cookie applies.

expires

the time at which this cookie expires, as a Time object.

secure

whether this cookie is a secure cookie or not (default to false). Secure cookies are only transmitted to HTTPS servers.

These keywords correspond to attributes of the cookie object.

# File lib/cgi/cookie.rb, line 65
def initialize(name = "", *value)
  @domain = nil
  @expires = nil
  if name.kind_of?(String)
    @name = name
    %r^(.*/)|.match(ENV["SCRIPT_NAME"])
    @path = ($1 or "")
    @secure = false
    return super(value)
  end

  options = name
  unless options.has_key?("name")
    raise ArgumentError, "`name' required"
  end

  @name = options["name"]
  value = Array(options["value"])
  # simple support for IE
  if options["path"]
    @path = options["path"]
  else
    %r^(.*/)|.match(ENV["SCRIPT_NAME"])
    @path = ($1 or "")
  end
  @domain = options["domain"]
  @expires = options["expires"]
  @secure = options["secure"] == true ? true : false

  super(value)
end
parse(raw_cookie) click to toggle source

Parse a raw cookie string into a hash of cookie-name=>Cookie pairs.

cookies = CGI::Cookie::parse("raw_cookie_string")
  # { "name1" => cookie1, "name2" => cookie2, ... }

# File lib/cgi/cookie.rb, line 145
def Cookie::parse(raw_cookie)
  cookies = Hash.new([])
  return cookies unless raw_cookie

  raw_cookie.split(/[;,]\s?/).each do |pairs|
    name, values = pairs.split('=',2)
    next unless name and values
    name = CGI::unescape(name)
    values ||= ""
    values = values.split('&').collect{|v| CGI::unescape(v,@@accept_charset) }
    if cookies.has_key?(name)
      values = cookies[name].value + values
    end
    cookies[name] = Cookie::new(name, *values)
  end

  cookies
end

Public Instance Methods

secure=(val) click to toggle source

Set whether the Cookie is a secure cookie or not.

val must be a boolean.

# File lib/cgi/cookie.rb, line 121
def secure=(val)
  @secure = val if val == true or val == false
  @secure
end
to_s() click to toggle source

Convert the Cookie to its string representation.

# File lib/cgi/cookie.rb, line 127
def to_s
  val = collect{|v| CGI::escape(v) }.join("&")
  buf = "#{@name}=#{val}"
  buf << "; domain=#{@domain}" if @domain
  buf << "; path=#{@path}"     if @path
  buf << "; expires=#{CGI::rfc1123_date(@expires)}" if @expires
  buf << "; secure"            if @secure == true
  buf
end
value() click to toggle source

Returns the value or list of values for this cookie.

# File lib/cgi/cookie.rb, line 109
def value
  self
end
value=(val) click to toggle source

Replaces the value of this cookie with a new value or list of values.

# File lib/cgi/cookie.rb, line 114
def value=(val)
  replace(Array(val))
end


module CGI::HtmlExtension - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module CGI::HtmlExtension

Mixin module providing HTML generation methods.

For example,

cgi.a("http://www.example.com") { "Example" }
  # => "<A HREF=\"http://www.example.com\">Example</A>"

Modules Html3, Html4, etc., contain more basic HTML-generation methods (#title, #h1, etc.).

See class CGI for a detailed example.

In Files

  • lib/cgi/html.rb

Public Instance Methods

a(href = "") { || ... } click to toggle source

Generate an Anchor element as a string.

href can either be a string, giving the URL for the HREF attribute, or it can be a hash of the element's attributes.

The body of the element is the string returned by the no-argument block passed in.

a("http://www.example.com") { "Example" }
  # => "<A HREF=\"http://www.example.com\">Example</A>"

a("HREF" => "http://www.example.com", "TARGET" => "_top") { "Example" }
  # => "<A HREF=\"http://www.example.com\" TARGET=\"_top\">Example</A>"

# File lib/cgi/html.rb, line 89
def a(href = "") # :yield:
  attributes = if href.kind_of?(String)
                 { "HREF" => href }
               else
                 href
               end
  if block_given?
    super(attributes){ yield }
  else
    super(attributes)
  end
end
base(href = "") { || ... } click to toggle source

Generate a Document Base URI element as a String.

href can either by a string, giving the base URL for the HREF attribute, or it can be a has of the element's attributes.

The passed-in no-argument block is ignored.

base("http://www.example.com/cgi")
  # => "<BASE HREF=\"http://www.example.com/cgi\">"

# File lib/cgi/html.rb, line 111
def base(href = "") # :yield:
  attributes = if href.kind_of?(String)
                 { "HREF" => href }
               else
                 href
               end
  if block_given?
    super(attributes){ yield }
  else
    super(attributes)
  end
end
blockquote(cite = {}) { || ... } click to toggle source

Generate a BlockQuote element as a string.

cite can either be a string, give the URI for the source of the quoted text, or a hash, giving all attributes of the element, or it can be omitted, in which case the element has no attributes.

The body is provided by the passed-in no-argument block

blockquote("http://www.example.com/quotes/foo.html") { "Foo!" }
  #=> "<BLOCKQUOTE CITE=\"http://www.example.com/quotes/foo.html\">Foo!</BLOCKQUOTE>

# File lib/cgi/html.rb, line 134
def blockquote(cite = {})  # :yield:
  attributes = if cite.kind_of?(String)
                 { "CITE" => cite }
               else
                 cite
               end
  if block_given?
    super(attributes){ yield }
  else
    super(attributes)
  end
end
caption(align = {}) { || ... } click to toggle source

Generate a Table Caption element as a string.

align can be a string, giving the alignment of the caption (one of top, bottom, left, or right). It can be a hash of all the attributes of the element. Or it can be omitted.

The body of the element is provided by the passed-in no-argument block.

caption("left") { "Capital Cities" }
  # => <CAPTION ALIGN=\"left\">Capital Cities</CAPTION>

# File lib/cgi/html.rb, line 158
def caption(align = {}) # :yield:
  attributes = if align.kind_of?(String)
                 { "ALIGN" => align }
               else
                 align
               end
  if block_given?
    super(attributes){ yield }
  else
    super(attributes)
  end
end
checkbox(name = "", value = nil, checked = nil) click to toggle source

Generate a Checkbox Input element as a string.

The attributes of the element can be specified as three arguments, name, value, and checked. checked is a boolean value; if true, the CHECKED attribute will be included in the element.

Alternatively, the attributes can be specified as a hash.

checkbox("name")
  # = checkbox("NAME" => "name")

checkbox("name", "value")
  # = checkbox("NAME" => "name", "VALUE" => "value")

checkbox("name", "value", true)
  # = checkbox("NAME" => "name", "VALUE" => "value", "CHECKED" => true)

# File lib/cgi/html.rb, line 188
def checkbox(name = "", value = nil, checked = nil)
  attributes = if name.kind_of?(String)
                 { "TYPE" => "checkbox", "NAME" => name,
                   "VALUE" => value, "CHECKED" => checked }
               else
                 name["TYPE"] = "checkbox"
                 name
               end
  input(attributes)
end
checkbox_group(name = "", *values) click to toggle source

Generate a sequence of checkbox elements, as a String.

The checkboxes will all have the same name attribute. Each checkbox is followed by a label. There will be one checkbox for each value. Each value can be specified as a String, which will be used both as the value of the VALUE attribute and as the label for that checkbox. A single-element array has the same effect.

Each value can also be specified as a three-element array. The first element is the VALUE attribute; the second is the label; and the third is a boolean specifying whether this checkbox is CHECKED.

Each value can also be specified as a two-element array, by omitting either the value element (defaults to the same as the label), or the boolean checked element (defaults to false).

checkbox_group("name", "foo", "bar", "baz")
  # <INPUT TYPE="checkbox" NAME="name" VALUE="foo">foo
  # <INPUT TYPE="checkbox" NAME="name" VALUE="bar">bar
  # <INPUT TYPE="checkbox" NAME="name" VALUE="baz">baz

checkbox_group("name", ["foo"], ["bar", true], "baz")
  # <INPUT TYPE="checkbox" NAME="name" VALUE="foo">foo
  # <INPUT TYPE="checkbox" CHECKED NAME="name" VALUE="bar">bar
  # <INPUT TYPE="checkbox" NAME="name" VALUE="baz">baz

checkbox_group("name", ["1", "Foo"], ["2", "Bar", true], "Baz")
  # <INPUT TYPE="checkbox" NAME="name" VALUE="1">Foo
  # <INPUT TYPE="checkbox" CHECKED NAME="name" VALUE="2">Bar
  # <INPUT TYPE="checkbox" NAME="name" VALUE="Baz">Baz

checkbox_group("NAME" => "name",
                 "VALUES" => ["foo", "bar", "baz"])

checkbox_group("NAME" => "name",
                 "VALUES" => [["foo"], ["bar", true], "baz"])

checkbox_group("NAME" => "name",
                 "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"])

# File lib/cgi/html.rb, line 242
def checkbox_group(name = "", *values)
  if name.kind_of?(Hash)
    values = name["VALUES"]
    name = name["NAME"]
  end
  values.collect{|value|
    if value.kind_of?(String)
      checkbox(name, value) + value
    else
      if value[-1] == true || value[-1] == false
        checkbox(name, value[0],  value[-1]) +
        value[-2]
      else
        checkbox(name, value[0]) +
        value[-1]
      end
    end
  }.join
end
file_field(name = "", size = 20, maxlength = nil) click to toggle source

Generate an File Upload Input element as a string.

The attributes of the element can be specified as three arguments, name, size, and maxlength. maxlength is the maximum length of the file's name, not of the file's contents.

Alternatively, the attributes can be specified as a hash.

See multipart_form() for forms that include file uploads.

file_field("name")
  # <INPUT TYPE="file" NAME="name" SIZE="20">

file_field("name", 40)
  # <INPUT TYPE="file" NAME="name" SIZE="40">

file_field("name", 40, 100)
  # <INPUT TYPE="file" NAME="name" SIZE="40" MAXLENGTH="100">

file_field("NAME" => "name", "SIZE" => 40)
  # <INPUT TYPE="file" NAME="name" SIZE="40">

# File lib/cgi/html.rb, line 284
def file_field(name = "", size = 20, maxlength = nil)
  attributes = if name.kind_of?(String)
                 { "TYPE" => "file", "NAME" => name,
                   "SIZE" => size.to_s }
               else
                 name["TYPE"] = "file"
                 name
               end
  attributes["MAXLENGTH"] = maxlength.to_s if maxlength
  input(attributes)
end
form(method = "post", action = script_name, enctype = "application/x-www-form-urlencoded") { || ... } click to toggle source

Generate a Form element as a string.

method should be either “get” or “post”, and defaults to the latter. action defaults to the current CGI script name. enctype defaults to “application/x-www-form-urlencoded”.

Alternatively, the attributes can be specified as a hash.

See also multipart_form() for forms that include file uploads.

form{ "string" }
  # <FORM METHOD="post" ENCTYPE="application/x-www-form-urlencoded">string</FORM>

form("get") { "string" }
  # <FORM METHOD="get" ENCTYPE="application/x-www-form-urlencoded">string</FORM>

form("get", "url") { "string" }
  # <FORM METHOD="get" ACTION="url" ENCTYPE="application/x-www-form-urlencoded">string</FORM>

form("METHOD" => "post", "ENCTYPE" => "enctype") { "string" }
  # <FORM METHOD="post" ENCTYPE="enctype">string</FORM>

# File lib/cgi/html.rb, line 318
def form(method = "post", action = script_name, enctype = "application/x-www-form-urlencoded")
  attributes = if method.kind_of?(String)
                 { "METHOD" => method, "ACTION" => action,
                   "ENCTYPE" => enctype }
               else
                 unless method.has_key?("METHOD")
                   method["METHOD"] = "post"
                 end
                 unless method.has_key?("ENCTYPE")
                   method["ENCTYPE"] = enctype
                 end
                 method
               end
  if block_given?
    body = yield
  else
    body = ""
  end
  if @output_hidden
    body << @output_hidden.collect{|k,v|
      "<INPUT TYPE=\"HIDDEN\" NAME=\"#{k}\" VALUE=\"#{v}\">"
    }.join
  end
  super(attributes){body}
end
hidden(name = "", value = nil) click to toggle source

Generate a Hidden Input element as a string.

The attributes of the element can be specified as two arguments, name and value.

Alternatively, the attributes can be specified as a hash.

hidden("name")
  # <INPUT TYPE="hidden" NAME="name">

hidden("name", "value")
  # <INPUT TYPE="hidden" NAME="name" VALUE="value">

hidden("NAME" => "name", "VALUE" => "reset", "ID" => "foo")
  # <INPUT TYPE="hidden" NAME="name" VALUE="value" ID="foo">

# File lib/cgi/html.rb, line 359
def hidden(name = "", value = nil)
  attributes = if name.kind_of?(String)
                 { "TYPE" => "hidden", "NAME" => name, "VALUE" => value }
               else
                 name["TYPE"] = "hidden"
                 name
               end
  input(attributes)
end
html(attributes = {}) { || ... } click to toggle source

Generate a top-level HTML element as a string.

The attributes of the element are specified as a hash. The pseudo-attribute “PRETTY” can be used to specify that the generated HTML string should be indented. “PRETTY” can also be specified as a string as the sole argument to this method. The pseudo-attribute “DOCTYPE”, if given, is used as the leading DOCTYPE SGML tag; it should include the entire text of this tag, including angle brackets.

The body of the html element is supplied as a block.

html{ "string" }
  # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML>string</HTML>

html("LANG" => "ja") { "string" }
  # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML LANG="ja">string</HTML>

html("DOCTYPE" => false) { "string" }
  # <HTML>string</HTML>

html("DOCTYPE" => '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">') { "string" }
  # <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><HTML>string</HTML>

html("PRETTY" => "  ") { "<BODY></BODY>" }
  # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
  # <HTML>
  #   <BODY>
  #   </BODY>
  # </HTML>

html("PRETTY" => "\t") { "<BODY></BODY>" }
  # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
  # <HTML>
  #         <BODY>
  #         </BODY>
  # </HTML>

html("PRETTY") { "<BODY></BODY>" }
  # = html("PRETTY" => "  ") { "<BODY></BODY>" }

html(if $VERBOSE then "PRETTY" end) { "HTML string" }

# File lib/cgi/html.rb, line 411
def html(attributes = {}) # :yield:
  if nil == attributes
    attributes = {}
  elsif "PRETTY" == attributes
    attributes = { "PRETTY" => true }
  end
  pretty = attributes.delete("PRETTY")
  pretty = "  " if true == pretty
  buf = ""

  if attributes.has_key?("DOCTYPE")
    if attributes["DOCTYPE"]
      buf << attributes.delete("DOCTYPE")
    else
      attributes.delete("DOCTYPE")
    end
  else
    buf << doctype
  end

  if block_given?
    buf << super(attributes){ yield }
  else
    buf << super(attributes)
  end

  if pretty
    CGI::pretty(buf, pretty)
  else
    buf
  end

end
image_button(src = "", name = nil, alt = nil) click to toggle source

Generate an Image Button Input element as a string.

src is the URL of the image to use for the button. name is the input name. alt is the alternative text for the image.

Alternatively, the attributes can be specified as a hash.

image_button("url")
  # <INPUT TYPE="image" SRC="url">

image_button("url", "name", "string")
  # <INPUT TYPE="image" SRC="url" NAME="name" ALT="string">

image_button("SRC" => "url", "ALT" => "string")
  # <INPUT TYPE="image" SRC="url" ALT="string">

# File lib/cgi/html.rb, line 460
def image_button(src = "", name = nil, alt = nil)
  attributes = if src.kind_of?(String)
                 { "TYPE" => "image", "SRC" => src, "NAME" => name,
                   "ALT" => alt }
               else
                 src["TYPE"] = "image"
                 src["SRC"] ||= ""
                 src
               end
  input(attributes)
end
img(src = "", alt = "", width = nil, height = nil) click to toggle source

Generate an Image element as a string.

src is the URL of the image. alt is the alternative text for the image. width is the width of the image, and height is its height.

Alternatively, the attributes can be specified as a hash.

img("src", "alt", 100, 50)
  # <IMG SRC="src" ALT="alt" WIDTH="100" HEIGHT="50">

img("SRC" => "src", "ALT" => "alt", "WIDTH" => 100, "HEIGHT" => 50)
  # <IMG SRC="src" ALT="alt" WIDTH="100" HEIGHT="50">

# File lib/cgi/html.rb, line 486
def img(src = "", alt = "", width = nil, height = nil)
  attributes = if src.kind_of?(String)
                 { "SRC" => src, "ALT" => alt }
               else
                 src
               end
  attributes["WIDTH"] = width.to_s if width
  attributes["HEIGHT"] = height.to_s if height
  super(attributes)
end
multipart_form(action = nil, enctype = "multipart/form-data") { || ... } click to toggle source

Generate a Form element with multipart encoding as a String.

Multipart encoding is used for forms that include file uploads.

action is the action to perform. enctype is the encoding type, which defaults to “multipart/form-data”.

Alternatively, the attributes can be specified as a hash.

multipart_form{ "string" }
  # <FORM METHOD="post" ENCTYPE="multipart/form-data">string</FORM>

multipart_form("url") { "string" }
  # <FORM METHOD="post" ACTION="url" ENCTYPE="multipart/form-data">string</FORM>
# File lib/cgi/html.rb, line 512
def multipart_form(action = nil, enctype = "multipart/form-data")
  attributes = if action == nil
                 { "METHOD" => "post", "ENCTYPE" => enctype }
               elsif action.kind_of?(String)
                 { "METHOD" => "post", "ACTION" => action,
                   "ENCTYPE" => enctype }
               else
                 unless action.has_key?("METHOD")
                   action["METHOD"] = "post"
                 end
                 unless action.has_key?("ENCTYPE")
                   action["ENCTYPE"] = enctype
                 end
                 action
               end
  if block_given?
    form(attributes){ yield }
  else
    form(attributes)
  end
end
password_field(name = "", value = nil, size = 40, maxlength = nil) click to toggle source

Generate a Password Input element as a string.

name is the name of the input field. value is its default value. size is the size of the input field display. maxlength is the maximum length of the inputted password.

Alternatively, attributes can be specified as a hash.

password_field("name")
  # <INPUT TYPE="password" NAME="name" SIZE="40">

password_field("name", "value")
  # <INPUT TYPE="password" NAME="name" VALUE="value" SIZE="40">

password_field("password", "value", 80, 200)
  # <INPUT TYPE="password" NAME="name" VALUE="value" SIZE="80" MAXLENGTH="200">

password_field("NAME" => "name", "VALUE" => "value")
  # <INPUT TYPE="password" NAME="name" VALUE="value">

# File lib/cgi/html.rb, line 554
def password_field(name = "", value = nil, size = 40, maxlength = nil)
  attributes = if name.kind_of?(String)
                 { "TYPE" => "password", "NAME" => name,
                   "VALUE" => value, "SIZE" => size.to_s }
               else
                 name["TYPE"] = "password"
                 name
               end
  attributes["MAXLENGTH"] = maxlength.to_s if maxlength
  input(attributes)
end
popup_menu(name = "", *values) click to toggle source

Generate a Select element as a string.

name is the name of the element. The values are the options that can be selected from the Select menu. Each value can be a String or a one, two, or three-element Array. If a String or a one-element Array, this is both the value of that option and the text displayed for it. If a three-element Array, the elements are the option value, displayed text, and a boolean value specifying whether this option starts as selected. The two-element version omits either the option value (defaults to the same as the display text) or the boolean selected specifier (defaults to false).

The attributes and options can also be specified as a hash. In this case, options are specified as an array of values as described above, with the hash key of “VALUES”.

popup_menu("name", "foo", "bar", "baz")
  # <SELECT NAME="name">
  #   <OPTION VALUE="foo">foo</OPTION>
  #   <OPTION VALUE="bar">bar</OPTION>
  #   <OPTION VALUE="baz">baz</OPTION>
  # </SELECT>

popup_menu("name", ["foo"], ["bar", true], "baz")
  # <SELECT NAME="name">
  #   <OPTION VALUE="foo">foo</OPTION>
  #   <OPTION VALUE="bar" SELECTED>bar</OPTION>
  #   <OPTION VALUE="baz">baz</OPTION>
  # </SELECT>

popup_menu("name", ["1", "Foo"], ["2", "Bar", true], "Baz")
  # <SELECT NAME="name">
  #   <OPTION VALUE="1">Foo</OPTION>
  #   <OPTION SELECTED VALUE="2">Bar</OPTION>
  #   <OPTION VALUE="Baz">Baz</OPTION>
  # </SELECT>

popup_menu("NAME" => "name", "SIZE" => 2, "MULTIPLE" => true,
            "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"])
  # <SELECT NAME="name" MULTIPLE SIZE="2">
  #   <OPTION VALUE="1">Foo</OPTION>
  #   <OPTION SELECTED VALUE="2">Bar</OPTION>
  #   <OPTION VALUE="Baz">Baz</OPTION>
  # </SELECT>

# File lib/cgi/html.rb, line 609
def popup_menu(name = "", *values)

  if name.kind_of?(Hash)
    values   = name["VALUES"]
    size     = name["SIZE"].to_s if name["SIZE"]
    multiple = name["MULTIPLE"]
    name     = name["NAME"]
  else
    size = nil
    multiple = nil
  end

  select({ "NAME" => name, "SIZE" => size,
           "MULTIPLE" => multiple }){
    values.collect{|value|
      if value.kind_of?(String)
        option({ "VALUE" => value }){ value }
      else
        if value[value.size - 1] == true
          option({ "VALUE" => value[0], "SELECTED" => true }){
            value[value.size - 2]
          }
        else
          option({ "VALUE" => value[0] }){
            value[value.size - 1]
          }
        end
      end
    }.join
  }

end
Also aliased as: scrolling_list
radio_button(name = "", value = nil, checked = nil) click to toggle source

Generates a radio-button Input element.

name is the name of the input field. value is the value of the field if checked. checked specifies whether the field starts off checked.

Alternatively, the attributes can be specified as a hash.

radio_button("name", "value")
  # <INPUT TYPE="radio" NAME="name" VALUE="value">

radio_button("name", "value", true)
  # <INPUT TYPE="radio" NAME="name" VALUE="value" CHECKED>

radio_button("NAME" => "name", "VALUE" => "value", "ID" => "foo")
  # <INPUT TYPE="radio" NAME="name" VALUE="value" ID="foo">

# File lib/cgi/html.rb, line 658
def radio_button(name = "", value = nil, checked = nil)
  attributes = if name.kind_of?(String)
                 { "TYPE" => "radio", "NAME" => name,
                   "VALUE" => value, "CHECKED" => checked }
               else
                 name["TYPE"] = "radio"
                 name
               end
  input(attributes)
end
radio_group(name = "", *values) click to toggle source

Generate a sequence of radio button Input elements, as a String.

This works the same as checkbox_group(). However, it is not valid to have more than one radiobutton in a group checked.

radio_group("name", "foo", "bar", "baz")
  # <INPUT TYPE="radio" NAME="name" VALUE="foo">foo
  # <INPUT TYPE="radio" NAME="name" VALUE="bar">bar
  # <INPUT TYPE="radio" NAME="name" VALUE="baz">baz

radio_group("name", ["foo"], ["bar", true], "baz")
  # <INPUT TYPE="radio" NAME="name" VALUE="foo">foo
  # <INPUT TYPE="radio" CHECKED NAME="name" VALUE="bar">bar
  # <INPUT TYPE="radio" NAME="name" VALUE="baz">baz

radio_group("name", ["1", "Foo"], ["2", "Bar", true], "Baz")
  # <INPUT TYPE="radio" NAME="name" VALUE="1">Foo
  # <INPUT TYPE="radio" CHECKED NAME="name" VALUE="2">Bar
  # <INPUT TYPE="radio" NAME="name" VALUE="Baz">Baz

radio_group("NAME" => "name",
              "VALUES" => ["foo", "bar", "baz"])

radio_group("NAME" => "name",
              "VALUES" => [["foo"], ["bar", true], "baz"])

radio_group("NAME" => "name",
              "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"])

# File lib/cgi/html.rb, line 697
def radio_group(name = "", *values)
  if name.kind_of?(Hash)
    values = name["VALUES"]
    name = name["NAME"]
  end
  values.collect{|value|
    if value.kind_of?(String)
      radio_button(name, value) + value
    else
      if value[-1] == true || value[-1] == false
        radio_button(name, value[0],  value[-1]) +
        value[-2]
      else
        radio_button(name, value[0]) +
        value[-1]
      end
    end
  }.join
end
reset(value = nil, name = nil) click to toggle source

Generate a reset button Input element, as a String.

This resets the values on a form to their initial values. value is the text displayed on the button. name is the name of this button.

Alternatively, the attributes can be specified as a hash.

reset
  # <INPUT TYPE="reset">

reset("reset")
  # <INPUT TYPE="reset" VALUE="reset">

reset("VALUE" => "reset", "ID" => "foo")
  # <INPUT TYPE="reset" VALUE="reset" ID="foo">

# File lib/cgi/html.rb, line 732
def reset(value = nil, name = nil)
  attributes = if (not value) or value.kind_of?(String)
                 { "TYPE" => "reset", "VALUE" => value, "NAME" => name }
               else
                 value["TYPE"] = "reset"
                 value
               end
  input(attributes)
end
scrolling_list(name = "", *values) click to toggle source
Alias for: popup_menu
submit(value = nil, name = nil) click to toggle source

Generate a submit button Input element, as a String.

value is the text to display on the button. name is the name of the input.

Alternatively, the attributes can be specified as a hash.

submit
  # <INPUT TYPE="submit">

submit("ok")
  # <INPUT TYPE="submit" VALUE="ok">

submit("ok", "button1")
  # <INPUT TYPE="submit" VALUE="ok" NAME="button1">

submit("VALUE" => "ok", "NAME" => "button1", "ID" => "foo")
  # <INPUT TYPE="submit" VALUE="ok" NAME="button1" ID="foo">

# File lib/cgi/html.rb, line 762
def submit(value = nil, name = nil)
  attributes = if (not value) or value.kind_of?(String)
                 { "TYPE" => "submit", "VALUE" => value, "NAME" => name }
               else
                 value["TYPE"] = "submit"
                 value
               end
  input(attributes)
end
text_field(name = "", value = nil, size = 40, maxlength = nil) click to toggle source

Generate a text field Input element, as a String.

name is the name of the input field. value is its initial value. size is the size of the input area. maxlength is the maximum length of input accepted.

Alternatively, the attributes can be specified as a hash.

text_field("name")
  # <INPUT TYPE="text" NAME="name" SIZE="40">

text_field("name", "value")
  # <INPUT TYPE="text" NAME="name" VALUE="value" SIZE="40">

text_field("name", "value", 80)
  # <INPUT TYPE="text" NAME="name" VALUE="value" SIZE="80">

text_field("name", "value", 80, 200)
  # <INPUT TYPE="text" NAME="name" VALUE="value" SIZE="80" MAXLENGTH="200">

text_field("NAME" => "name", "VALUE" => "value")
  # <INPUT TYPE="text" NAME="name" VALUE="value">

# File lib/cgi/html.rb, line 794
def text_field(name = "", value = nil, size = 40, maxlength = nil)
  attributes = if name.kind_of?(String)
                 { "TYPE" => "text", "NAME" => name, "VALUE" => value,
                   "SIZE" => size.to_s }
               else
                 name["TYPE"] = "text"
                 name
               end
  attributes["MAXLENGTH"] = maxlength.to_s if maxlength
  input(attributes)
end
textarea(name = "", cols = 70, rows = 10) { || ... } click to toggle source

Generate a TextArea element, as a String.

name is the name of the textarea. cols is the number of columns and rows is the number of rows in the display.

Alternatively, the attributes can be specified as a hash.

The body is provided by the passed-in no-argument block

textarea("name")
   # = textarea("NAME" => "name", "COLS" => 70, "ROWS" => 10)

textarea("name", 40, 5)
   # = textarea("NAME" => "name", "COLS" => 40, "ROWS" => 5)

# File lib/cgi/html.rb, line 820
def textarea(name = "", cols = 70, rows = 10)  # :yield:
  attributes = if name.kind_of?(String)
                 { "NAME" => name, "COLS" => cols.to_s,
                   "ROWS" => rows.to_s }
               else
                 name
               end
  if block_given?
    super(attributes){ yield }
  else
    super(attributes)
  end
end


class CGI::InvalidEncoding - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CGI::InvalidEncoding

Exception raised when there is an invalid encoding detected

In Files

  • lib/cgi/core.rb

Parent

Exception


module CGI::QueryExtension - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module CGI::QueryExtension

Mixin module that provides the following:

  1. Access to the CGI environment variables as methods. See documentation to the CGI class for a list of these variables. The methods are exposed by removing the leading HTTP_ (if it exists) and downcasing the name. For example, auth_type will return the environment variable AUTH_TYPE, and accept will return the value for HTTP_ACCEPT.

  2. Access to cookies, including the cookies attribute.

  3. Access to parameters, including the params attribute, and overloading #[] to perform parameter value lookup by key.

  4. The initialize_query method, for initializing the above mechanisms, handling multipart forms, and allowing the class to be used in “offline” mode.

In Files

  • lib/cgi/core.rb

Attributes

cookies[RW]

Get the cookies as a hash of cookie-name=>Cookie pairs.

files[R]

Get the uploaded files as a hash of name=>values pairs

params[R]

Get the parameters as a hash of name=>values pairs, where values is an Array.

Public Instance Methods

[](key) click to toggle source

Get the value for the parameter with a given key.

If the parameter has multiple values, only the first will be retrieved; use params to get the array of values.

# File lib/cgi/core.rb, line 697
def [](key)
  params = @params[key]
  return '' unless params
  value = params[0]
  if @multipart
    if value
      return value
    elsif defined? StringIO
      StringIO.new("".force_encoding("ascii-8bit"))
    else
      Tempfile.new("CGI",encoding:"ascii-8bit")
    end
  else
    str = if value then value.dup else "" end
    str
  end
end
has_key?(*args) click to toggle source

Returns true if a given query string parameter exists.

# File lib/cgi/core.rb, line 721
def has_key?(*args)
  @params.has_key?(*args)
end
Also aliased as: key?, include?
include?(*args) click to toggle source
Alias for: has_key?
key?(*args) click to toggle source
Alias for: has_key?
keys(*args) click to toggle source

Return all query parameter names as an array of String.

# File lib/cgi/core.rb, line 716
def keys(*args)
  @params.keys(*args)
end
multipart?() click to toggle source

Returns whether the form contained multipart/form-data

# File lib/cgi/core.rb, line 689
def multipart?
  @multipart
end
params=(hash) click to toggle source

Set all the parameters.

# File lib/cgi/core.rb, line 458
def params=(hash)
  @params.clear
  @params.update(hash)
end
raw_cookie() click to toggle source

Get the raw cookies as a string.

# File lib/cgi/core.rb, line 438
def raw_cookie
  env_table["HTTP_COOKIE"]
end
raw_cookie2() click to toggle source

Get the raw RFC2965 cookies as a string.

# File lib/cgi/core.rb, line 443
def raw_cookie2
  env_table["HTTP_COOKIE2"]
end


class CGI::Session - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CGI::Session

Overview

This file provides the CGI::Session class, which provides session support for CGI scripts. A session is a sequence of HTTP requests and responses linked together and associated with a single client. Information associated with the session is stored on the server between requests. A session id is passed between client and server with every request and response, transparently to the user. This adds state information to the otherwise stateless HTTP request/response protocol.

Lifecycle

A CGI::Session instance is created from a CGI object. By default, this CGI::Session instance will start a new session if none currently exists, or continue the current session for this client if one does exist. The new_session option can be used to either always or never create a new session. See new() for more details.

delete() deletes a session from session storage. It does not however remove the session id from the client. If the client makes another request with the same id, the effect will be to start a new session with the old session's id.

Setting and retrieving session data.

The Session class associates data with a session as key-value pairs. This data can be set and retrieved by indexing the Session instance using '[]', much the same as hashes (although other hash methods are not supported).

When session processing has been completed for a request, the session should be closed using the close() method. This will store the session's state to persistent storage. If you want to store the session's state to persistent storage without finishing session processing for this request, call the update() method.

Storing session state

The caller can specify what form of storage to use for the session's data with the database_manager option to ::new. The following storage classes are provided as part of the standard library:

CGI::Session::FileStore

stores data as plain text in a flat file. Only works with String data. This is the default storage type.

CGI::Session::MemoryStore

stores data in an in-memory hash. The data only persists for as long as the current ruby interpreter instance does.

CGI::Session::PStore

stores data in Marshalled format. Provided by cgi/session/pstore.rb. Supports data of any type, and provides file-locking and transaction support.

Custom storage types can also be created by defining a class with the following methods:

new(session, options)
restore  # returns hash of session data.
update
close
delete

Changing storage type mid-session does not work. Note in particular that by default the FileStore and PStore session data files have the same name. If your application switches from one to the other without making sure that filenames will be different and clients still have old sessions lying around in cookies, then things will break nastily!

Maintaining the session id.

Most session state is maintained on the server. However, a session id must be passed backwards and forwards between client and server to maintain a reference to this session state.

The simplest way to do this is via cookies. The CGI::Session class provides transparent support for session id communication via cookies if the client has cookies enabled.

If the client has cookies disabled, the session id must be included as a parameter of all requests sent by the client to the server. The CGI::Session class in conjunction with the CGI class will transparently add the session id as a hidden input field to all forms generated using the CGI#form() HTML generation method. No built-in support is provided for other mechanisms, such as URL re-writing. The caller is responsible for extracting the session id from the #session_id attribute and manually encoding it in URLs and adding it as a hidden input to HTML forms created by other mechanisms. Also, session expiry is not automatically handled.

Examples of use

Setting the user's name

require 'cgi'
require 'cgi/session'
require 'cgi/session/pstore'     # provides CGI::Session::PStore

cgi = CGI.new("html4")

session = CGI::Session.new(cgi,
    'database_manager' => CGI::Session::PStore,  # use PStore
    'session_key' => '_rb_sess_id',              # custom session key
    'session_expires' => Time.now + 30 * 60,     # 30 minute timeout
    'prefix' => 'pstore_sid_')                   # PStore option
if cgi.has_key?('user_name') and cgi['user_name'] != ''
    # coerce to String: cgi[] returns the
    # string-like CGI::QueryExtension::Value
    session['user_name'] = cgi['user_name'].to_s
elsif !session['user_name']
    session['user_name'] = "guest"
end
session.close

Creating a new session safely

require 'cgi'
require 'cgi/session'

cgi = CGI.new("html4")

# We make sure to delete an old session if one exists,
# not just to free resources, but to prevent the session
# from being maliciously hijacked later on.
begin
    session = CGI::Session.new(cgi, 'new_session' => false)
    session.delete
rescue ArgumentError  # if no old session
end
session = CGI::Session.new(cgi, 'new_session' => true)
session.close

In Files

  • lib/cgi/session/pstore.rb
  • lib/cgi/session.rb

Parent

Object

Attributes

new_session[R]

The id of this session.

session_id[R]

The id of this session.

Public Class Methods

new(request, option={}) click to toggle source

Create a new CGI::Session object for request.

request is an instance of the CGI class (see cgi.rb). option is a hash of options for initialising this CGI::Session instance. The following options are recognised:

session_key

the parameter name used for the session id. Defaults to '_session_id'.

#session_id

the session id to use. If not provided, then it is retrieved from the session_key parameter of the request, or automatically generated for a new session.

#new_session

if true, force creation of a new session. If not set, a new session is only created if none currently exists. If false, a new session is never created, and if none currently exists and the session_id option is not set, an ArgumentError is raised.

database_manager

the name of the class providing storage facilities for session state persistence. Built-in support is provided for FileStore (the default), MemoryStore, and PStore (from cgi/session/pstore.rb). See the documentation for these classes for more details.

The following options are also recognised, but only apply if the session id is stored in a cookie.

session_expires

the time the current session expires, as a Time object. If not set, the session will terminate when the user's browser is closed.

session_domain

the hostname domain for which this session is valid. If not set, defaults to the hostname of the server.

session_secure

if true, this session will only work over HTTPS.

session_path

the path for which this session applies. Defaults to the directory of the CGI script.

option is also passed on to the session storage class initializer; see the documentation for each session storage class for the options they support.

The retrieved or created session is automatically added to request as a cookie, and also to its output_hidden table, which is used to add hidden input elements to forms.

WARNING the output_hidden fields are surrounded by a <fieldset> tag in HTML 4 generation, which is not invisible on many browsers; you may wish to disable the use of fieldsets with code similar to the following (see blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/37805)

cgi = CGI.new("html4")
class << cgi
    undef_method :fieldset
end

# File lib/cgi/session.rb, line 245
def initialize(request, option={})
  @new_session = false
  session_key = option['session_key'] || '_session_id'
  session_id = option['session_id']
  unless session_id
    if option['new_session']
      session_id = create_new_id
      @new_session = true
    end
  end
  unless session_id
    if request.key?(session_key)
      session_id = request[session_key]
      session_id = session_id.read if session_id.respond_to?(:read)
    end
    unless session_id
      session_id, = request.cookies[session_key]
    end
    unless session_id
      unless option.fetch('new_session', true)
        raise ArgumentError, "session_key `%s' should be supplied"%session_key
      end
      session_id = create_new_id
      @new_session = true
    end
  end
  @session_id = session_id
  dbman = option['database_manager'] || FileStore
  begin
    @dbman = dbman::new(self, option)
  rescue NoSession
    unless option.fetch('new_session', true)
      raise ArgumentError, "invalid session_id `%s'"%session_id
    end
    session_id = @session_id = create_new_id unless session_id
    @new_session=true
    retry
  end
  request.instance_eval do
    @output_hidden = {session_key => session_id} unless option['no_hidden']
    @output_cookies =  [
      Cookie::new("name" => session_key,
      "value" => session_id,
      "expires" => option['session_expires'],
      "domain" => option['session_domain'],
      "secure" => option['session_secure'],
      "path" =>
      if option['session_path']
        option['session_path']
      elsif ENV["SCRIPT_NAME"]
        File::dirname(ENV["SCRIPT_NAME"])
      else
      ""
      end)
    ] unless option['no_cookies']
  end
  @dbprot = [@dbman]
  ObjectSpace::define_finalizer(self, Session::callback(@dbprot))
end

Public Instance Methods

[](key) click to toggle source

Retrieve the session data for key key.

# File lib/cgi/session.rb, line 306
def [](key)
  @data ||= @dbman.restore
  @data[key]
end
[]=(key, val) click to toggle source

Set the session data for key key.

# File lib/cgi/session.rb, line 312
def []=(key, val)
  @write_lock ||= true
  @data ||= @dbman.restore
  @data[key] = val
end
close() click to toggle source

Store session data on the server and close the session storage. For some session storage types, this is a no-op.

# File lib/cgi/session.rb, line 326
def close
  @dbman.close
  @dbprot.clear
end
delete() click to toggle source

Delete the session from storage. Also closes the storage.

Note that the session's data is not automatically deleted upon the session expiring.

# File lib/cgi/session.rb, line 335
def delete
  @dbman.delete
  @dbprot.clear
end
update() click to toggle source

Store session data on the server. For some session storage types, this is a no-op.

# File lib/cgi/session.rb, line 320
def update
  @dbman.update
end


class CGI::Session::FileStore - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CGI::Session::FileStore

File-based session storage class.

Implements session storage as a flat file of 'key=value' values. This storage type only works directly with String values; the user is responsible for converting other types to Strings when storing and from Strings when retrieving.

In Files

  • lib/cgi/session.rb

Parent

Object

Public Class Methods

new(session, option={}) click to toggle source

Create a new FileStore instance.

This constructor is used internally by CGI::Session. The user does not generally need to call it directly.

session is the session for which this instance is being created. The session id must only contain alphanumeric characters; automatically generated session ids observe this requirement.

option is a hash of options for the initializer. The following options are recognised:

tmpdir

the directory to use for storing the FileStore file. Defaults to Dir.tmpdir (generally “/tmp” on Unix systems).

prefix

the prefix to add to the session id when generating the filename for this session's FileStore file. Defaults to “cgi_sid_”.

suffix

the prefix to add to the session id when generating the filename for this session's FileStore file. Defaults to the empty string.

This session's FileStore file will be created if it does not exist, or opened if it does.

# File lib/cgi/session.rb, line 372
def initialize(session, option={})
  dir = option['tmpdir'] || Dir::tmpdir
  prefix = option['prefix'] || 'cgi_sid_'
  suffix = option['suffix'] || ''
  id = session.session_id
  require 'digest/md5'
  md5 = Digest::MD5.hexdigest(id)[0,16]
  @path = dir+"/"+prefix+md5+suffix
  if File::exist? @path
    @hash = nil
  else
    unless session.new_session
      raise CGI::Session::NoSession, "uninitialized session"
    end
    @hash = {}
  end
end

Public Instance Methods

close() click to toggle source

Update and close the session's FileStore file.

# File lib/cgi/session.rb, line 432
def close
  update
end
delete() click to toggle source

Close and delete the session's FileStore file.

# File lib/cgi/session.rb, line 437
def delete
  File::unlink @path+".lock" rescue nil
  File::unlink @path+".new" rescue nil
  File::unlink @path rescue Errno::ENOENT
end
restore() click to toggle source

Restore session state from the session's FileStore file.

Returns the session state as a hash.

# File lib/cgi/session.rb, line 393
def restore
  unless @hash
    @hash = {}
    begin
      lockf = File.open(@path+".lock", "r")
      lockf.flock File::LOCK_SH
      f = File.open(@path, 'r')
      for line in f
        line.chomp!
        k, v = line.split('=',2)
        @hash[CGI::unescape(k)] = Marshal.restore(CGI::unescape(v))
      end
    ensure
      f.close unless f.nil?
      lockf.close if lockf
    end
  end
  @hash
end
update() click to toggle source

Save session state to the session's FileStore file.

# File lib/cgi/session.rb, line 414
def update
  return unless @hash
  begin
    lockf = File.open(@path+".lock", File::CREAT|File::RDWR, 0600)
    lockf.flock File::LOCK_EX
    f = File.open(@path+".new", File::CREAT|File::TRUNC|File::WRONLY, 0600)
    for k,v in @hash
      f.printf "%s=%s\n", CGI::escape(k), CGI::escape(String(Marshal.dump(v)))
    end
    f.close
    File.rename @path+".new", @path
  ensure
    f.close if f and !f.closed?
    lockf.close if lockf
  end
end


class CGI::Session::MemoryStore - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CGI::Session::MemoryStore

In-memory session storage class.

Implements session storage as a global in-memory hash. Session data will only persist for as long as the ruby interpreter instance does.

In Files

  • lib/cgi/session.rb

Parent

Object

Public Class Methods

new(session, option=nil) click to toggle source

Create a new MemoryStore instance.

session is the session this instance is associated with. option is a list of initialisation options. None are currently recognised.

# File lib/cgi/session.rb, line 457
def initialize(session, option=nil)
  @session_id = session.session_id
  unless GLOBAL_HASH_TABLE.key?(@session_id)
    unless session.new_session
      raise CGI::Session::NoSession, "uninitialized session"
    end
    GLOBAL_HASH_TABLE[@session_id] = {}
  end
end

Public Instance Methods

close() click to toggle source

Close session storage.

A no-op.

# File lib/cgi/session.rb, line 484
def close
  # don't need to close
end
delete() click to toggle source

Delete the session state.

# File lib/cgi/session.rb, line 489
def delete
  GLOBAL_HASH_TABLE.delete(@session_id)
end
restore() click to toggle source

Restore session state.

Returns session data as a hash.

# File lib/cgi/session.rb, line 470
def restore
  GLOBAL_HASH_TABLE[@session_id]
end
update() click to toggle source

Update session state.

A no-op.

# File lib/cgi/session.rb, line 477
def update
  # don't need to update; hash is shared
end


class CGI::Session::NullStore - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CGI::Session::NullStore

Dummy session storage class.

Implements session storage place holder. No actual storage will be done.

In Files

  • lib/cgi/session.rb

Parent

Object

Public Class Methods

new(session, option=nil) click to toggle source

Create a new NullStore instance.

session is the session this instance is associated with. option is a list of initialisation options. None are currently recognised.

# File lib/cgi/session.rb, line 504
def initialize(session, option=nil)
end

Public Instance Methods

close() click to toggle source

Close session storage.

A no-op.

# File lib/cgi/session.rb, line 521
def close
end
delete() click to toggle source

Delete the session state.

A no-op.

# File lib/cgi/session.rb, line 527
def delete
end
restore() click to toggle source

Restore (empty) session state.

# File lib/cgi/session.rb, line 508
def restore
  {}
end
update() click to toggle source

Update session state.

A no-op.

# File lib/cgi/session.rb, line 515
def update
end


class CGI::Session::PStore - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CGI::Session::PStore

PStore-based session storage class.

This builds upon the top-level PStore class provided by the library file pstore.rb. Session data is marshalled and stored in a file. File locking and transaction services are provided.

In Files

  • lib/cgi/session/pstore.rb

Parent

Object

Public Class Methods

new(session, option={}) click to toggle source

Create a new CGI::Session::PStore instance

This constructor is used internally by CGI::Session. The user does not generally need to call it directly.

session is the session for which this instance is being created. The session id must only contain alphanumeric characters; automatically generated session ids observe this requirement.

option is a hash of options for the initializer. The following options are recognised:

tmpdir

the directory to use for storing the PStore file. Defaults to Dir.tmpdir (generally “/tmp” on Unix systems).

prefix

the prefix to add to the session id when generating the filename for this session's PStore file. Defaults to the empty string.

This session's PStore file will be created if it does not exist, or opened if it does.

# File lib/cgi/session/pstore.rb, line 45
def initialize(session, option={})
  dir = option['tmpdir'] || Dir::tmpdir
  prefix = option['prefix'] || ''
  id = session.session_id
  require 'digest/md5'
  md5 = Digest::MD5.hexdigest(id)[0,16]
  path = dir+"/"+prefix+md5
  path.untaint
  if File::exist?(path)
    @hash = nil
  else
    unless session.new_session
      raise CGI::Session::NoSession, "uninitialized session"
    end
    @hash = {}
  end
  @p = ::PStore.new(path)
  @p.transaction do |p|
    File.chmod(0600, p.path)
  end
end

Public Instance Methods

close() click to toggle source

Update and close the session's PStore file.

# File lib/cgi/session/pstore.rb, line 87
def close
  update
end
delete() click to toggle source

Close and delete the session's PStore file.

# File lib/cgi/session/pstore.rb, line 92
def delete
  path = @p.path
  File::unlink path
end
restore() click to toggle source

Restore session state from the session's PStore file.

Returns the session state as a hash.

# File lib/cgi/session/pstore.rb, line 70
def restore
  unless @hash
    @p.transaction do
      @hash = @p['hash'] || {}
    end
  end
  @hash
end
update() click to toggle source

Save session state to the session's PStore file.

# File lib/cgi/session/pstore.rb, line 80
def update
  @p.transaction do
    @p['hash'] = @hash
  end
end


module CMath - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module CMath

CMath

CMath is a library that provides trigonometric and transcendental functions for complex numbers.

Usage

To start using this library, simply:

require "cmath"

Square root of a negative number is a complex number.

CMath.sqrt(-9)  #=> 0+3.0i

In Files

  • lib/cmath.rb

Included Modules

  • Math

Public Class Methods

acos(z) click to toggle source

returns the arc cosine of z

# File lib/cmath.rb, line 257
def acos(z)
  begin
    if z.real? and z >= -1 and z <= 1
      acos!(z)
    else
      (-1.0).i * log(z + 1.0.i * sqrt(1.0 - z * z))
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: acos!
acos!(z) click to toggle source
Alias for: acos
acosh(z) click to toggle source

returns the inverse hyperbolic cosine of z

# File lib/cmath.rb, line 314
def acosh(z)
  begin
    if z.real? and z >= 1
      acosh!(z)
    else
      log(z + sqrt(z * z - 1.0))
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: acosh!
acosh!(z) click to toggle source
Alias for: acosh
asin(z) click to toggle source

returns the arc sine of z

# File lib/cmath.rb, line 243
def asin(z)
  begin
    if z.real? and z >= -1 and z <= 1
      asin!(z)
    else
      (-1.0).i * log(1.0.i * z + sqrt(1.0 - z * z))
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: asin!
asin!(z) click to toggle source
Alias for: asin
asinh(z) click to toggle source

returns the inverse hyperbolic sine of z

# File lib/cmath.rb, line 300
def asinh(z)
  begin
    if z.real?
      asinh!(z)
    else
      log(z + sqrt(1.0 + z * z))
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: asinh!
asinh!(z) click to toggle source
Alias for: asinh
atan(z) click to toggle source

returns the arc tangent of z

# File lib/cmath.rb, line 271
def atan(z)
  begin
    if z.real?
      atan!(z)
    else
      1.0.i * log((1.0.i + z) / (1.0.i - z)) / 2.0
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: atan!
atan!(z) click to toggle source
Alias for: atan
atan2(y,x) click to toggle source

returns the arc tangent of y divided by x using the signs of y and x to determine the quadrant

# File lib/cmath.rb, line 286
def atan2(y,x)
  begin
    if y.real? and x.real?
      atan2!(y,x)
    else
      (-1.0).i * log((x + 1.0.i * y) / sqrt(x * x + y * y))
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: atan2!
atan2!(y,x) click to toggle source
Alias for: atan2
atanh(z) click to toggle source

returns the inverse hyperbolic tangent of z

# File lib/cmath.rb, line 328
def atanh(z)
  begin
    if z.real? and z >= -1 and z <= 1
      atanh!(z)
    else
      log((1.0 + z) / (1.0 - z)) / 2.0
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: atanh!
atanh!(z) click to toggle source
Alias for: atanh
cbrt(z) click to toggle source

returns the principal value of the cube root of z

# File lib/cmath.rb, line 149
def cbrt(z)
  z ** (1.0/3)
end
Also aliased as: cbrt!
cbrt!(z) click to toggle source
Alias for: cbrt
cos(z) click to toggle source

returns the cosine of z, where z is given in radians

# File lib/cmath.rb, line 170
def cos(z)
  begin
    if z.real?
      cos!(z)
    else
      Complex(cos!(z.real) * cosh!(z.imag),
              -sin!(z.real) * sinh!(z.imag))
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: cos!
cos!(z) click to toggle source
Alias for: cos
cosh(z) click to toggle source

returns the hyperbolic cosine of z, where z is given in radians

# File lib/cmath.rb, line 214
def cosh(z)
  begin
    if z.real?
      cosh!(z)
    else
      Complex(cosh!(z.real) * cos!(z.imag),
              sinh!(z.real) * sin!(z.imag))
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: cosh!
cosh!(z) click to toggle source
Alias for: cosh
exp(z) click to toggle source

Math::E raised to the z power

exp(Complex(0,0))      #=> 1.0+0.0i
exp(Complex(0,PI))     #=> -1.0+1.2246467991473532e-16i
exp(Complex(0,PI/2.0)) #=> 6.123233995736766e-17+1.0i

# File lib/cmath.rb, line 52
def exp(z)
  begin
    if z.real?
      exp!(z)
    else
      ere = exp!(z.real)
      Complex(ere * cos!(z.imag),
              ere * sin!(z.imag))
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: exp!
exp!(z) click to toggle source
Alias for: exp
log(*args) click to toggle source

Returns the natural logarithm of Complex. If a second argument is given, it will be the base of logarithm.

log(Complex(0,0)) #=> -Infinity+0.0i

# File lib/cmath.rb, line 71
def log(*args)
  begin
    z, b = args
    unless b.nil? || b.kind_of?(Numeric)
      raise TypeError,  "Numeric Number required"
    end
    if z.real? and z >= 0 and (b.nil? or b >= 0)
      log!(*args)
    else
      a = Complex(log!(z.abs), z.arg)
      if b
        a /= log(b)
      end
      a
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: log!
log!(*args) click to toggle source
Alias for: log
log10(z) click to toggle source

returns the base 10 logarithm of z

# File lib/cmath.rb, line 107
def log10(z)
  begin
    if z.real? and z >= 0
      log10!(z)
    else
      log(z) / log!(10)
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: log10!
log10!(z) click to toggle source
Alias for: log10
log2(z) click to toggle source

returns the base 2 logarithm of z

# File lib/cmath.rb, line 93
def log2(z)
  begin
    if z.real? and z >= 0
      log2!(z)
    else
      log(z) / log!(2)
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: log2!
log2!(z) click to toggle source
Alias for: log2
sin(z) click to toggle source

returns the sine of z, where z is given in radians

# File lib/cmath.rb, line 155
def sin(z)
  begin
    if z.real?
      sin!(z)
    else
      Complex(sin!(z.real) * cosh!(z.imag),
              cos!(z.real) * sinh!(z.imag))
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: sin!
sin!(z) click to toggle source
Alias for: sin
sinh(z) click to toggle source

returns the hyperbolic sine of z, where z is given in radians

# File lib/cmath.rb, line 199
def sinh(z)
  begin
    if z.real?
      sinh!(z)
    else
      Complex(sinh!(z.real) * cos!(z.imag),
              cosh!(z.real) * sin!(z.imag))
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: sinh!
sinh!(z) click to toggle source
Alias for: sinh
sqrt(z) click to toggle source

Returns the non-negative square root of Complex.

sqrt(-1)            #=> 0+1.0i
sqrt(Complex(-1,0)) #=> 0.0+1.0i
sqrt(Complex(0,8))  #=> 2.0+2.0i

# File lib/cmath.rb, line 124
def sqrt(z)
  begin
    if z.real?
      if z < 0
        Complex(0, sqrt!(-z))
      else
        sqrt!(z)
      end
    else
      if z.imag < 0 ||
          (z.imag == 0 && z.imag.to_s[0] == '-')
        sqrt(z.conjugate).conjugate
      else
        r = z.abs
        x = z.real
        Complex(sqrt!((r + x) / 2.0), sqrt!((r - x) / 2.0))
      end
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: sqrt!
sqrt!(z) click to toggle source
Alias for: sqrt
tan(z) click to toggle source

returns the tangent of z, where z is given in radians

# File lib/cmath.rb, line 185
def tan(z)
  begin
    if z.real?
      tan!(z)
    else
      sin(z) / cos(z)
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: tan!
tan!(z) click to toggle source
Alias for: tan
tanh(z) click to toggle source

returns the hyperbolic tangent of z, where z is given in radians

# File lib/cmath.rb, line 229
def tanh(z)
  begin
    if z.real?
      tanh!(z)
    else
      sinh(z) / cosh(z)
    end
  rescue NoMethodError
    handle_no_method_error
  end
end
Also aliased as: tanh!
tanh!(z) click to toggle source
Alias for: tanh


class CSV - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CSV

This class provides a complete interface to CSV files and data. It offers tools to enable you to read and write to and from Strings or IO objects, as needed.

Reading

From a File

A Line at a Time

CSV.foreach("path/to/file.csv") do |row|
  # use row here...
end

All at Once

arr_of_arrs = CSV.read("path/to/file.csv")

From a String

A Line at a Time

CSV.parse("CSV,data,String") do |row|
  # use row here...
end

All at Once

arr_of_arrs = CSV.parse("CSV,data,String")

Writing

To a File

CSV.open("path/to/file.csv", "wb") do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
  # ...
end

To a String

csv_string = CSV.generate do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
  # ...
end

Convert a Single Line

csv_string = ["CSV", "data"].to_csv   # to CSV
csv_array  = "CSV,String".parse_csv   # from CSV

Shortcut Interface

CSV             { |csv_out| csv_out << %w{my data here} }  # to $stdout
CSV(csv = "")   { |csv_str| csv_str << %w{my data here} }  # to a String
CSV($stderr)    { |csv_err| csv_err << %w{my data here} }  # to $stderr
CSV($stdin)     { |csv_in|  csv_in.each { |row| p row } }  # from $stdin

Advanced Usage

Wrap an IO Object

csv = CSV.new(io, options)
# ... read (with gets() or each()) from and write (with <<) to csv here ...

CSV and Character Encodings (M17n or Multilingualization)

This new CSV parser is m17n savvy. The parser works in the Encoding of the IO or String object being read from or written to. Your data is never transcoded (unless you ask Ruby to transcode it for you) and will literally be parsed in the Encoding it is in. Thus CSV will return Arrays or Rows of Strings in the Encoding of your data. This is accomplished by transcoding the parser itself into your Encoding.

Some transcoding must take place, of course, to accomplish this multiencoding support. For example, :col_sep, :row_sep, and :quote_char must be transcoded to match your data. Hopefully this makes the entire process feel transparent, since CSV's defaults should just magically work for you data. However, you can set these values manually in the target Encoding to avoid the translation.

It's also important to note that while all of CSV's core parser is now Encoding agnostic, some features are not. For example, the built-in converters will try to transcode data to UTF-8 before making conversions. Again, you can provide custom converters that are aware of your Encodings to avoid this translation. It's just too hard for me to support native conversions in all of Ruby's Encodings.

Anyway, the practical side of this is simple: make sure IO and String objects passed into CSV have the proper Encoding set and everything should just work. CSV methods that allow you to open IO objects (::foreach, ::open, ::read, and ::readlines) do allow you to specify the Encoding.

One minor exception comes when generating CSV into a String with an Encoding that is not ASCII compatible. There's no existing data for CSV to use to prepare itself and thus you will probably need to manually specify the desired Encoding for most of those cases. It will try to guess using the fields in a row of output though, when using ::generate_line or Array#to_csv().

I try to point out any other Encoding issues in the documentation of methods as they come up.

This has been tested to the best of my ability with all non-“dummy” Encodings Ruby ships with. However, it is brave new code and may have some bugs. Please feel free to report any issues you find with it.

In Files

  • lib/csv.rb

Parent

Object

Included Modules

  • Enumerable

Constants

ConverterEncoding

The encoding used by all converters.

Converters

This Hash holds the built-in converters of CSV that can be accessed by name. You can select Converters with #convert or through the options Hash passed to ::new.

:integer

Converts any field Integer() accepts.

:float

Converts any field Float() accepts.

:numeric

A combination of :integer and :float.

:date

Converts any field Date.parse accepts.

:date_time

Converts any field DateTime.parse accepts.

:all

All built-in converters. A combination of :date_time and :numeric.

All built-in converters transcode field data to UTF-8 before attempting a conversion. If your data cannot be transcoded to UTF-8 the conversion will fail and the field will remain unchanged.

This Hash is intentionally left unfrozen and users should feel free to add values to it that can be accessed by all CSV objects.

To add a combo field, the value should be an Array of names. Combo fields can be nested with other combo fields.

DEFAULT_OPTIONS

The options used when no overrides are given by calling code. They are:

:col_sep

","

:row_sep

:auto

:quote_char

'"'

:field_size_limit

nil

:converters

nil

:unconverted_fields

nil

:headers

false

:return_headers

false

:header_converters

nil

:skip_blanks

false

:force_quotes

false

:skip_lines

nil

DateMatcher

A Regexp used to find and convert some common Date formats.

DateTimeMatcher

A Regexp used to find and convert some common DateTime formats.

FieldInfo

A FieldInfo Struct contains details about a field's position in the data source it was read from. CSV will pass this Struct to some blocks that make decisions based on field structure. See CSV.convert_fields() for an example.

index

The zero-based index of the field in its row.

line

The line of the data source this row is from.

header

The header for the column, when available.

HeaderConverters

This Hash holds the built-in header converters of CSV that can be accessed by name. You can select HeaderConverters with #header_convert or through the options Hash passed to ::new.

:downcase

Calls downcase() on the header String.

:symbol

The header String is downcased, spaces are replaced with underscores, non-word characters are dropped, and finally to_sym() is called.

All built-in header converters transcode header data to UTF-8 before attempting a conversion. If your data cannot be transcoded to UTF-8 the conversion will fail and the header will remain unchanged.

This Hash is intetionally left unfrozen and users should feel free to add values to it that can be accessed by all CSV objects.

To add a combo field, the value should be an Array of names. Combo fields can be nested with other combo fields.

VERSION

The version of the installed library.

Attributes

col_sep[R]

The encoded :col_sep used in parsing and writing. See ::new for details.

encoding[R]

The Encoding CSV is parsing or writing in. This will be the Encoding you receive parsed data in and/or the Encoding data will be written in.

field_size_limit[R]

The limit for field size, if any. See ::new for details.

lineno[R]

The line number of the last row read from this file. Fields with nested line-end characters will not affect this count.

quote_char[R]

The encoded :quote_char used in parsing and writing. See ::new for details.

row_sep[R]

The encoded :row_sep used in parsing and writing. See ::new for details.

skip_lines[R]

The regex marking a line as a comment. See ::new for details

Public Class Methods

filter( options = Hash.new ) { |row| ... } click to toggle source
filter( input, options = Hash.new ) { |row| ... }
filter( input, output, options = Hash.new ) { |row| ... }

This method is a convenience for building Unix-like filters for CSV data. Each row is yielded to the provided block which can alter it as needed. After the block returns, the row is appended to output altered or not.

The input and output arguments can be anything ::new accepts (generally String or IO objects). If not given, they default to ARGF and $stdout.

The options parameter is also filtered down to ::new after some clever key parsing. Any key beginning with :in_ or :input_ will have that leading identifier stripped and will only be used in the options Hash for the input object. Keys starting with :out_ or :output_ affect only output. All other keys are assigned to both objects.

The :output_row_sep option defaults to $INPUT_RECORD_SEPARATOR ($/).

# File lib/csv.rb, line 1076
def self.filter(*args)
  # parse options for input, output, or both
  in_options, out_options = Hash.new, {row_sep: $INPUT_RECORD_SEPARATOR}
  if args.last.is_a? Hash
    args.pop.each do |key, value|
      case key.to_s
      when /\Ain(?:put)?_(.+)\Z/
        in_options[$1.to_sym] = value
      when /\Aout(?:put)?_(.+)\Z/
        out_options[$1.to_sym] = value
      else
        in_options[key]  = value
        out_options[key] = value
      end
    end
  end
  # build input and output wrappers
  input  = new(args.shift || ARGF,    in_options)
  output = new(args.shift || $stdout, out_options)

  # read, yield, write
  input.each do |row|
    yield row
    output << row
  end
end
foreach(path, options = Hash.new, &block) click to toggle source

This method is intended as the primary interface for reading CSV files. You pass a path and any options you wish to set for the read. Each row of file will be passed to the provided block in turn.

The options parameter can be anything ::new understands. This method also understands an additional :encoding parameter that you can use to specify the Encoding of the data in the file to be read. You must provide this unless your data is in Encoding::default_external(). CSV will use this to determine how to parse the data. You may provide a second Encoding to have the data transcoded as it is read. For example, encoding: "UTF-32BE:UTF-8" would read UTF-32BE data from the file but transcode it to UTF-8 before CSV parses it.

# File lib/csv.rb, line 1117
def self.foreach(path, options = Hash.new, &block)
  open(path, options) do |csv|
    csv.each(&block)
  end
end
generate( str, options = Hash.new ) { |csv| ... } click to toggle source
generate( options = Hash.new ) { |csv| ... }

This method wraps a String you provide, or an empty default String, in a CSV object which is passed to the provided block. You can use the block to append CSV rows to the String and when the block exits, the final String will be returned.

Note that a passed String is modfied by this method. Call dup() before passing if you need a new String.

The options parameter can be anything ::new understands. This method understands an additional :encoding parameter when not passed a String to set the base Encoding for the output. CSV needs this hint if you plan to output non-ASCII compatible data.

# File lib/csv.rb, line 1141
def self.generate(*args)
  # add a default empty String, if none was given
  if args.first.is_a? String
    io = StringIO.new(args.shift)
    io.seek(0, IO::SEEK_END)
    args.unshift(io)
  else
    encoding = args[-1][:encoding] if args.last.is_a?(Hash)
    str      = ""
    str.force_encoding(encoding) if encoding
    args.unshift(str)
  end
  csv = new(*args)  # wrap
  yield csv         # yield for appending
  csv.string        # return final String
end
generate_line(row, options = Hash.new) click to toggle source

This method is a shortcut for converting a single row (Array) into a CSV String.

The options parameter can be anything ::new understands. This method understands an additional :encoding parameter to set the base Encoding for the output. This method will try to guess your Encoding from the first non-nil field in row, if possible, but you may need to use this parameter as a backup plan.

The :row_sep option defaults to $INPUT_RECORD_SEPARATOR ($/) when calling this method.

# File lib/csv.rb, line 1171
def self.generate_line(row, options = Hash.new)
  options  = {row_sep: $INPUT_RECORD_SEPARATOR}.merge(options)
  encoding = options.delete(:encoding)
  str      = ""
  if encoding
    str.force_encoding(encoding)
  elsif field = row.find { |f| not f.nil? }
    str.force_encoding(String(field).encoding)
  end
  (new(str, options) << row).string
end
instance(data = $stdout, options = Hash.new) { |instance| ... } click to toggle source

This method will return a CSV instance, just like ::new, but the instance will be cached and returned for all future calls to this method for the same data object (tested by Object#object_id()) with the same options.

If a block is given, the instance is passed to the block and the return value becomes the return value of the block.

# File lib/csv.rb, line 1036
def self.instance(data = $stdout, options = Hash.new)
  # create a _signature_ for this method call, data object and options
  sig = [data.object_id] +
        options.values_at(*DEFAULT_OPTIONS.keys.sort_by { |sym| sym.to_s })

  # fetch or create the instance for this signature
  @@instances ||= Hash.new
  instance    =   (@@instances[sig] ||= new(data, options))

  if block_given?
    yield instance  # run block, if given, returning result
  else
    instance        # or return the instance
  end
end
new(data, options = Hash.new) click to toggle source

This constructor will wrap either a String or IO object passed in data for reading and/or writing. In addition to the CSV instance methods, several IO methods are delegated. (See ::open for a complete list.) If you pass a String for data, you can later retrieve it (after writing to it, for example) with CSV.string().

Note that a wrapped String will be positioned at at the beginning (for reading). If you want it at the end (for writing), use ::generate. If you want any other positioning, pass a preset StringIO object instead.

You may set any reading and/or writing preferences in the options Hash. Available options are:

:col_sep

The String placed between each field. This String will be transcoded into the data's Encoding before parsing.

:row_sep

The String appended to the end of each row. This can be set to the special :auto setting, which requests that CSV automatically discover this from the data. Auto-discovery reads ahead in the data looking for the next "\r\n", "\n", or "\r" sequence. A sequence will be selected even if it occurs in a quoted field, assuming that you would have the same line endings there. If none of those sequences is found, data is ARGF, STDIN, STDOUT, or STDERR, or the stream is only available for output, the default $INPUT_RECORD_SEPARATOR ($/) is used. Obviously, discovery takes a little time. Set manually if speed is important. Also note that IO objects should be opened in binary mode on Windows if this feature will be used as the line-ending translation can cause problems with resetting the document position to where it was before the read ahead. This String will be transcoded into the data's Encoding before parsing.

:quote_char

The character used to quote fields. This has to be a single character String. This is useful for application that incorrectly use ' as the quote character instead of the correct ". CSV will always consider a double sequence this character to be an escaped quote. This String will be transcoded into the data's Encoding before parsing.

:field_size_limit

This is a maximum size CSV will read ahead looking for the closing quote for a field. (In truth, it reads to the first line ending beyond this size.) If a quote cannot be found within the limit CSV will raise a MalformedCSVError, assuming the data is faulty. You can use this limit to prevent what are effectively DoS attacks on the parser. However, this limit can cause a legitimate parse to fail and thus is set to nil, or off, by default.

:converters

An Array of names from the Converters Hash and/or lambdas that handle custom conversion. A single converter doesn't have to be in an Array. All built-in converters try to transcode fields to UTF-8 before converting. The conversion will fail if the data cannot be transcoded, leaving the field unchanged.

:unconverted_fields

If set to true, an unconverted_fields() method will be added to all returned rows (Array or CSV::Row) that will return the fields as they were before conversion. Note that :headers supplied by Array or String were not fields of the document and thus will have an empty Array attached.

:headers

If set to :first_row or true, the initial row of the CSV file will be treated as a row of headers. If set to an Array, the contents will be used as the headers. If set to a String, the String is run through a call of ::parse_line with the same :col_sep, :row_sep, and :quote_char as this instance to produce an Array of headers. This setting causes #shift to return rows as CSV::Row objects instead of Arrays and #read to return CSV::Table objects instead of an Array of Arrays.

:return_headers

When false, header rows are silently swallowed. If set to true, header rows are returned in a CSV::Row object with identical headers and fields (save that the fields do not go through the converters).

:write_headers

When true and :headers is set, a header row will be added to the output.

:header_converters

Identical in functionality to :converters save that the conversions are only made to header rows. All built-in converters try to transcode headers to UTF-8 before converting. The conversion will fail if the data cannot be transcoded, leaving the header unchanged.

:skip_blanks

When set to a true value, CSV will skip over any rows with no content.

:force_quotes

When set to a true value, CSV will quote all CSV fields it creates.

:skip_lines

When set to an object responding to match, every line matching it is considered a comment and ignored during parsing. When set to nil no line is considered a comment. If the passed object does not respond to match, ArgumentError is thrown.

See CSV::DEFAULT_OPTIONS for the default settings.

Options cannot be overridden in the instance methods for performance reasons, so be sure to set what you want here.

# File lib/csv.rb, line 1482
def initialize(data, options = Hash.new)
  # build the options for this read/write
  options = DEFAULT_OPTIONS.merge(options)

  # create the IO object we will read from
  @io       = data.is_a?(String) ? StringIO.new(data) : data
  # honor the IO encoding if we can, otherwise default to ASCII-8BIT
  @encoding = raw_encoding(nil) ||
              ( if encoding = options.delete(:internal_encoding)
                  case encoding
                  when Encoding; encoding
                  else Encoding.find(encoding)
                  end
                end ) ||
              ( case encoding = options.delete(:encoding)
                when Encoding; encoding
                when /\A[^:]+/; Encoding.find($&)
                end ) ||
              Encoding.default_internal || Encoding.default_external
  #
  # prepare for building safe regular expressions in the target encoding,
  # if we can transcode the needed characters
  #
  @re_esc   =   "\\".encode(@encoding) rescue ""
  @re_chars =   /#{%"[-\\]\\[\\.^$?*+{}()|# \r\n\t\f\v]".encode(@encoding)}/

  init_separators(options)
  init_parsers(options)
  init_converters(options)
  init_headers(options)
  init_comments(options)

  @force_encoding = !!(encoding || options.delete(:encoding))
  options.delete(:internal_encoding)
  options.delete(:external_encoding)
  unless options.empty?
    raise ArgumentError, "Unknown options:  #{options.keys.join(', ')}."
  end

  # track our own lineno since IO gets confused about line-ends is CSV fields
  @lineno = 0
end
open( filename, mode = "rb", options = Hash.new ) { |faster_csv| ... } click to toggle source
open( filename, options = Hash.new ) { |faster_csv| ... }
open( filename, mode = "rb", options = Hash.new )
open( filename, options = Hash.new )

This method opens an IO object, and wraps that with CSV. This is intended as the primary interface for writing a CSV file.

You must pass a filename and may optionally add a mode for Ruby's open(). You may also pass an optional Hash containing any options ::new understands as the final argument.

This method works like Ruby's open() call, in that it will pass a CSV object to a provided block and close it when the block terminates, or it will return the CSV object when no block is provided. (Note: This is different from the Ruby 1.8 CSV library which passed rows to the block. Use ::foreach for that behavior.)

You must provide a mode with an embedded Encoding designator unless your data is in Encoding::default_external(). CSV will check the Encoding of the underlying IO object (set by the mode you pass) to determine how to parse the data. You may provide a second Encoding to have the data transcoded as it is read just as you can with a normal call to IO::open(). For example, "rb:UTF-32BE:UTF-8" would read UTF-32BE data from the file but transcode it to UTF-8 before CSV parses it.

An opened CSV object will delegate to many IO methods for convenience. You may call:

  • binmode()

  • binmode?()

  • close()

  • close_read()

  • close_write()

  • closed?()

  • eof()

  • eof?()

  • external_encoding()

  • fcntl()

  • fileno()

  • flock()

  • flush()

  • fsync()

  • internal_encoding()

  • ioctl()

  • isatty()

  • path()

  • pid()

  • pos()

  • pos=()

  • reopen()

  • seek()

  • stat()

  • sync()

  • sync=()

  • tell()

  • to_i()

  • to_io()

  • truncate()

  • tty?()

# File lib/csv.rb, line 1246
def self.open(*args)
  # find the +options+ Hash
  options = if args.last.is_a? Hash then args.pop else Hash.new end
  # wrap a File opened with the remaining +args+ with no newline
  # decorator
  file_opts = {universal_newline: false}.merge(options)
  begin
    f = File.open(*args, file_opts)
  rescue ArgumentError => e
    raise unless /needs binmode/ =~ e.message and args.size == 1
    args << "rb"
    file_opts = {encoding: Encoding.default_external}.merge(file_opts)
    retry
  end
  csv = new(f, options)

  # handle blocks like Ruby's open(), not like the CSV library
  if block_given?
    begin
      yield csv
    ensure
      csv.close
    end
  else
    csv
  end
end
parse( str, options = Hash.new ) { |row| ... } click to toggle source
parse( str, options = Hash.new )

This method can be used to easily parse CSV out of a String. You may either provide a block which will be called with each row of the String in turn, or just use the returned Array of Arrays (when no block is given).

You pass your str to read from, and an optional options Hash containing anything ::new understands.

# File lib/csv.rb, line 1286
def self.parse(*args, &block)
  csv = new(*args)
  if block.nil?  # slurp contents, if no block is given
    begin
      csv.read
    ensure
      csv.close
    end
  else           # or pass each row to a provided block
    csv.each(&block)
  end
end
parse_line(line, options = Hash.new) click to toggle source

This method is a shortcut for converting a single line of a CSV String into a into an Array. Note that if line contains multiple rows, anything beyond the first row is ignored.

The options parameter can be anything ::new understands.

# File lib/csv.rb, line 1306
def self.parse_line(line, options = Hash.new)
  new(line, options).shift
end
read(path, *options) click to toggle source

Use to slurp a CSV file into an Array of Arrays. Pass the path to the file and any options ::new understands. This method also understands an additional :encoding parameter that you can use to specify the Encoding of the data in the file to be read. You must provide this unless your data is in Encoding::default_external(). CSV will use this to determine how to parse the data. You may provide a second Encoding to have the data transcoded as it is read. For example, encoding: "UTF-32BE:UTF-8" would read UTF-32BE data from the file but transcode it to UTF-8 before CSV parses it.

# File lib/csv.rb, line 1321
def self.read(path, *options)
  open(path, *options) { |csv| csv.read }
end
readlines(*args) click to toggle source

Alias for ::read.

# File lib/csv.rb, line 1326
def self.readlines(*args)
  read(*args)
end
table(path, options = Hash.new) click to toggle source

A shortcut for:

CSV.read( path, { headers:           true,
                  converters:        :numeric,
                  header_converters: :symbol }.merge(options) )
# File lib/csv.rb, line 1337
def self.table(path, options = Hash.new)
  read( path, { headers:           true,
                converters:        :numeric,
                header_converters: :symbol }.merge(options) )
end

Public Instance Methods

<<(row) click to toggle source

The primary write method for wrapped Strings and IOs, row (an Array or CSV::Row) is converted to CSV and appended to the data source. When a CSV::Row is passed, only the row's fields() are appended to the output.

The data source must be open for writing.

# File lib/csv.rb, line 1635
def <<(row)
  # make sure headers have been assigned
  if header_row? and [Array, String].include? @use_headers.class
    parse_headers  # won't read data for Array or String
    self << @headers if @write_headers
  end

  # handle CSV::Row objects and Hashes
  row = case row
        when self.class::Row then row.fields
        when Hash            then @headers.map { |header| row[header] }
        else                      row
        end

  @headers =  row if header_row?
  @lineno  += 1

  output = row.map(&@quote).join(@col_sep) + @row_sep  # quote and separate
  if @io.is_a?(StringIO)             and
     output.encoding != (encoding = raw_encoding)
    if @force_encoding
      output = output.encode(encoding)
    elsif (compatible_encoding = Encoding.compatible?(@io.string, output))
      @io.set_encoding(compatible_encoding)
      @io.seek(0, IO::SEEK_END)
    end
  end
  @io << output

  self  # for chaining
end
Also aliased as: add_row, puts
add_row(row) click to toggle source
Alias for: <<
convert( name ) click to toggle source
convert { |field| ... }
convert { |field, field_info| ... }

You can use this method to install a CSV::Converters built-in, or provide a block that handles a custom conversion.

If you provide a block that takes one argument, it will be passed the field and is expected to return the converted value or the field itself. If your block takes two arguments, it will also be passed a CSV::FieldInfo Struct, containing details about the field. Again, the block should return a converted field or the field itself.

# File lib/csv.rb, line 1684
def convert(name = nil, &converter)
  add_converter(:converters, self.class::Converters, name, &converter)
end
converters() click to toggle source

Returns the current list of converters in effect. See ::new for details. Built-in converters will be returned by name, while others will be returned as is.

# File lib/csv.rb, line 1551
def converters
  @converters.map do |converter|
    name = Converters.rassoc(converter)
    name ? name.first : converter
  end
end
each() { |row| ... } click to toggle source

Yields each row of the data source in turn.

Support for Enumerable.

The data source must be open for reading.

# File lib/csv.rb, line 1715
def each
  if block_given?
    while row = shift
      yield row
    end
  else
    to_enum
  end
end
force_quotes?() click to toggle source

Returns true if all output fields are quoted. See ::new for details.

# File lib/csv.rb, line 1594
def force_quotes?()       @force_quotes       end
gets() click to toggle source
Alias for: shift
header_convert( name ) click to toggle source
header_convert { |field| ... }
header_convert { |field, field_info| ... }

Identical to #convert, but for header rows.

Note that this method must be called before header rows are read to have any effect.

# File lib/csv.rb, line 1699
def header_convert(name = nil, &converter)
  add_converter( :header_converters,
                 self.class::HeaderConverters,
                 name,
                 &converter )
end
header_converters() click to toggle source

Returns the current list of converters in effect for headers. See ::new for details. Built-in converters will be returned by name, while others will be returned as is.

# File lib/csv.rb, line 1582
def header_converters
  @header_converters.map do |converter|
    name = HeaderConverters.rassoc(converter)
    name ? name.first : converter
  end
end
header_row?() click to toggle source

Returns true if the next row read will be a header row.

# File lib/csv.rb, line 1741
def header_row?
  @use_headers and @headers.nil?
end
headers() click to toggle source

Returns nil if headers will not be used, true if they will but have not yet been read, or the actual headers after they have been read. See ::new for details.

# File lib/csv.rb, line 1567
def headers
  @headers || true if @use_headers
end
inspect() click to toggle source

Returns a simplified description of the key CSV attributes in an ASCII compatible String.

# File lib/csv.rb, line 1902
def inspect
  str = ["<#", self.class.to_s, " io_type:"]
  # show type of wrapped IO
  if    @io == $stdout then str << "$stdout"
  elsif @io == $stdin  then str << "$stdin"
  elsif @io == $stderr then str << "$stderr"
  else                      str << @io.class.to_s
  end
  # show IO.path(), if available
  if @io.respond_to?(:path) and (p = @io.path)
    str << " io_path:" << p.inspect
  end
  # show encoding
  str << " encoding:" << @encoding.name
  # show other attributes
  %w[ lineno     col_sep     row_sep
      quote_char skip_blanks ].each do |attr_name|
    if a = instance_variable_get("@#{attr_name}")
      str << " " << attr_name << ":" << a.inspect
    end
  end
  if @use_headers
    str << " headers:" << headers.inspect
  end
  str << ">"
  begin
    str.join('')
  rescue  # any encoding error
    str.map do |s|
      e = Encoding::Converter.asciicompat_encoding(s.encoding)
      e ? s.encode(e) : s.force_encoding("ASCII-8BIT")
    end.join('')
  end
end
puts(row) click to toggle source
Alias for: <<
read() click to toggle source

Slurps the remaining rows and returns an Array of Arrays.

The data source must be open for reading.

# File lib/csv.rb, line 1730
def read
  rows = to_a
  if @use_headers
    Table.new(rows)
  else
    rows
  end
end
Also aliased as: readlines
readline() click to toggle source
Alias for: shift
readlines() click to toggle source
Alias for: read
return_headers?() click to toggle source

Returns true if headers will be returned as a row of results. See ::new for details.

# File lib/csv.rb, line 1574
def return_headers?()     @return_headers     end
rewind() click to toggle source

Rewinds the underlying IO object and resets CSV's lineno() counter.

# File lib/csv.rb, line 1619
def rewind
  @headers = nil
  @lineno  = 0

  @io.rewind
end
shift() click to toggle source

The primary read method for wrapped Strings and IOs, a single row is pulled from the data source, parsed and returned as an Array of fields (if header rows are not used) or a CSV::Row (when header rows are used).

The data source must be open for reading.

# File lib/csv.rb, line 1752
def shift
  #########################################################################
  ### This method is purposefully kept a bit long as simple conditional ###
  ### checks are faster than numerous (expensive) method calls.         ###
  #########################################################################

  # handle headers not based on document content
  if header_row? and @return_headers and
     [Array, String].include? @use_headers.class
    if @unconverted_fields
      return add_unconverted_fields(parse_headers, Array.new)
    else
      return parse_headers
    end
  end

  #
  # it can take multiple calls to <tt>@io.gets()</tt> to get a full line,
  # because of \r and/or \n characters embedded in quoted fields
  #
  in_extended_col = false
  csv             = Array.new

  loop do
    # add another read to the line
    unless parse = @io.gets(@row_sep)
      return nil
    end

    parse.sub!(@parsers[:line_end], "")

    if csv.empty?
      #
      # I believe a blank line should be an <tt>Array.new</tt>, not Ruby 1.8
      # CSV's <tt>[nil]</tt>
      #
      if parse.empty?
        @lineno += 1
        if @skip_blanks
          next
        elsif @unconverted_fields
          return add_unconverted_fields(Array.new, Array.new)
        elsif @use_headers
          return self.class::Row.new(Array.new, Array.new)
        else
          return Array.new
        end
      end
    end

    next if @skip_lines and @skip_lines.match parse

    parts =  parse.split(@col_sep, -1)
    if parts.empty?
      if in_extended_col
        csv[-1] << @col_sep   # will be replaced with a @row_sep after the parts.each loop
      else
        csv << nil
      end
    end

    # This loop is the hot path of csv parsing. Some things may be non-dry
    # for a reason. Make sure to benchmark when refactoring.
    parts.each do |part|
      if in_extended_col
        # If we are continuing a previous column
        if part[-1] == @quote_char && part.count(@quote_char) % 2 != 0
          # extended column ends
          csv.last << part[0..-2]
          if csv.last =~ @parsers[:stray_quote]
            raise MalformedCSVError,
                  "Missing or stray quote in line #{lineno + 1}"
          end
          csv.last.gsub!(@quote_char * 2, @quote_char)
          in_extended_col = false
        else
          csv.last << part
          csv.last << @col_sep
        end
      elsif part[0] == @quote_char
        # If we are staring a new quoted column
        if part[-1] != @quote_char || part.count(@quote_char) % 2 != 0
          # start an extended column
          csv             << part[1..-1]
          csv.last        << @col_sep
          in_extended_col =  true
        else
          # regular quoted column
          csv << part[1..-2]
          if csv.last =~ @parsers[:stray_quote]
            raise MalformedCSVError,
                  "Missing or stray quote in line #{lineno + 1}"
          end
          csv.last.gsub!(@quote_char * 2, @quote_char)
        end
      elsif part =~ @parsers[:quote_or_nl]
        # Unquoted field with bad characters.
        if part =~ @parsers[:nl_or_lf]
          raise MalformedCSVError, "Unquoted fields do not allow " +
                                   "\\r or \\n (line #{lineno + 1})."
        else
          raise MalformedCSVError, "Illegal quoting in line #{lineno + 1}."
        end
      else
        # Regular ole unquoted field.
        csv << (part.empty? ? nil : part)
      end
    end

    # Replace tacked on @col_sep with @row_sep if we are still in an extended
    # column.
    csv[-1][-1] = @row_sep if in_extended_col

    if in_extended_col
      # if we're at eof?(), a quoted field wasn't closed...
      if @io.eof?
        raise MalformedCSVError,
              "Unclosed quoted field on line #{lineno + 1}."
      elsif @field_size_limit and csv.last.size >= @field_size_limit
        raise MalformedCSVError, "Field size exceeded on line #{lineno + 1}."
      end
      # otherwise, we need to loop and pull some more data to complete the row
    else
      @lineno += 1

      # save fields unconverted fields, if needed...
      unconverted = csv.dup if @unconverted_fields

      # convert fields, if needed...
      csv = convert_fields(csv) unless @use_headers or @converters.empty?
      # parse out header rows and handle CSV::Row conversions...
      csv = parse_headers(csv)  if     @use_headers

      # inject unconverted fields and accessor, if requested...
      if @unconverted_fields and not csv.respond_to? :unconverted_fields
        add_unconverted_fields(csv, unconverted)
      end

      # return the results
      break csv
    end
  end
end
Also aliased as: gets, readline
skip_blanks?() click to toggle source

Returns true blank lines are skipped by the parser. See ::new for details.

# File lib/csv.rb, line 1592
def skip_blanks?()        @skip_blanks        end
unconverted_fields?() click to toggle source

Returns true if unconverted_fields() to parsed results. See ::new for details.

# File lib/csv.rb, line 1561
def unconverted_fields?() @unconverted_fields end
write_headers?() click to toggle source

Returns true if headers are written in output. See ::new for details.

# File lib/csv.rb, line 1576
def write_headers?()      @write_headers      end


class CSV::MalformedCSVError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CSV::MalformedCSVError

The error thrown when the parser encounters illegal CSV formatting.

In Files

  • lib/csv.rb

Parent

RuntimeError


class CSV::Row - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CSV::Row

A CSV::Row is part Array and part Hash. It retains an order for the fields and allows duplicates just as an Array would, but also allows you to access fields by name just as you could if they were in a Hash.

All rows returned by CSV will be constructed from this class, if header row processing is activated.

In Files

  • lib/csv.rb

Parent

Object

Included Modules

  • Enumerable

Attributes

row[R]

Internal data format used to compare equality.

Public Class Methods

new(headers, fields, header_row = false) click to toggle source

Construct a new CSV::Row from headers and fields, which are expected to be Arrays. If one Array is shorter than the other, it will be padded with nil objects.

The optional header_row parameter can be set to true to indicate, via #header_row? and #field_row?, that this is a header row. Otherwise, the row is assumes to be a field row.

A CSV::Row object supports the following Array methods through delegation:

  • empty?()

  • length()

  • size()

# File lib/csv.rb, line 235
def initialize(headers, fields, header_row = false)
  @header_row = header_row

  # handle extra headers or fields
  @row = if headers.size > fields.size
    headers.zip(fields)
  else
    fields.zip(headers).map { |pair| pair.reverse }
  end
end

Public Instance Methods

<<( field ) click to toggle source
<<( header_and_field_array )
<<( header_and_field_hash )

If a two-element Array is provided, it is assumed to be a header and field and the pair is appended. A Hash works the same way with the key being the header and the value being the field. Anything else is assumed to be a lone field which is appended with a nil header.

This method returns the row for chaining.

# File lib/csv.rb, line 375
def <<(arg)
  if arg.is_a?(Array) and arg.size == 2  # appending a header and name
    @row << arg
  elsif arg.is_a?(Hash)                  # append header and name pairs
    arg.each { |pair| @row << pair }
  else                                   # append field value
    @row << [nil, arg]
  end

  self  # for chaining
end
==(other) click to toggle source

Returns true if this row contains the same headers and fields in the same order as other.

# File lib/csv.rb, line 512
def ==(other)
  return @row == other.row if other.is_a? CSV::Row
  @row == other
end
[](header_or_index, minimum_index = 0) click to toggle source
Alias for: field
[]=( header, value ) click to toggle source
[]=( header, offset, value )
[]=( index, value )

Looks up the field by the semantics described in #field and assigns the value.

Assigning past the end of the row with an index will set all pairs between to [nil, nil]. Assigning to an unused header appends the new pair.

# File lib/csv.rb, line 342
def []=(*args)
  value = args.pop

  if args.first.is_a? Integer
    if @row[args.first].nil?  # extending past the end with index
      @row[args.first] = [nil, value]
      @row.map! { |pair| pair.nil? ? [nil, nil] : pair }
    else                      # normal index assignment
      @row[args.first][1] = value
    end
  else
    index = index(*args)
    if index.nil?             # appending a field
      self << [args.first, value]
    else                      # normal header assignment
      @row[index][1] = value
    end
  end
end
delete( header ) click to toggle source
delete( header, offset )
delete( index )

Used to remove a pair from the row by header or index. The pair is located as described in #field. The deleted pair is returned, or nil if a pair could not be found.

# File lib/csv.rb, line 410
def delete(header_or_index, minimum_index = 0)
  if header_or_index.is_a? Integer                 # by index
    @row.delete_at(header_or_index)
  elsif i = index(header_or_index, minimum_index)  # by header
    @row.delete_at(i)
  else
    [ ]
  end
end
delete_if(&block) click to toggle source

The provided block is passed a header and field for each pair in the row and expected to return true or false, depending on whether the pair should be deleted.

This method returns the row for chaining.

# File lib/csv.rb, line 427
def delete_if(&block)
  @row.delete_if(&block)

  self  # for chaining
end
each(&block) click to toggle source

Yields each pair of the row as header and field tuples (much like iterating over a Hash).

Support for Enumerable.

This method returns the row for chaining.

# File lib/csv.rb, line 502
def each(&block)
  @row.each(&block)

  self  # for chaining
end
fetch( header ) click to toggle source
fetch( header ) { |row| ... }
fetch( header, default )

This method will fetch the field value by header. It has the same behavior as Hash#fetch: if there is a field with the given header, its value is returned. Otherwise, if a block is given, it is yielded the header and its result is returned; if a default is given as the second argument, it is returned; otherwise a KeyError is raised.

# File lib/csv.rb, line 305
def fetch(header, *varargs)
  raise ArgumentError, "Too many arguments" if varargs.length > 1
  pair = @row.assoc(header)
  if pair
    pair.last
  else
    if block_given?
      yield header
    elsif varargs.empty?
      raise KeyError, "key not found: #{header}"
    else
      varargs.first
    end
  end
end
field( header ) click to toggle source
field( header, offset )
field( index )

This method will return the field value by header or index. If a field is not found, nil is returned.

When provided, offset ensures that a header match occurrs on or later than the offset index. You can use this to find duplicate headers, without resorting to hard-coding exact indices.

# File lib/csv.rb, line 283
def field(header_or_index, minimum_index = 0)
  # locate the pair
  finder = header_or_index.is_a?(Integer) ? :[] : :assoc
  pair   = @row[minimum_index..-1].send(finder, header_or_index)

  # return the field if we have a pair
  pair.nil? ? nil : pair.last
end
Also aliased as: []
field?(data) click to toggle source

Returns true if data matches a field in this row, and false otherwise.

# File lib/csv.rb, line 488
def field?(data)
  fields.include? data
end
field_row?() click to toggle source

Returns true if this is a field row.

# File lib/csv.rb, line 261
def field_row?
  not header_row?
end
fields(*headers_and_or_indices) click to toggle source

This method accepts any number of arguments which can be headers, indices, Ranges of either, or two-element Arrays containing a header and offset. Each argument will be replaced with a field lookup as described in #field.

If called with no arguments, all fields are returned.

# File lib/csv.rb, line 441
def fields(*headers_and_or_indices)
  if headers_and_or_indices.empty?  # return all fields--no arguments
    @row.map { |pair| pair.last }
  else                              # or work like values_at()
    headers_and_or_indices.inject(Array.new) do |all, h_or_i|
      all + if h_or_i.is_a? Range
        index_begin = h_or_i.begin.is_a?(Integer) ? h_or_i.begin :
                                                    index(h_or_i.begin)
        index_end   = h_or_i.end.is_a?(Integer)   ? h_or_i.end :
                                                    index(h_or_i.end)
        new_range   = h_or_i.exclude_end? ? (index_begin...index_end) :
                                            (index_begin..index_end)
        fields.values_at(new_range)
      else
        [field(*Array(h_or_i))]
      end
    end
  end
end
Also aliased as: values_at
has_key?(header) click to toggle source

Returns true if there is a field with the given header.

# File lib/csv.rb, line 322
def has_key?(header)
  !!@row.assoc(header)
end
Also aliased as: include?, key?, member?
header?(name) click to toggle source

Returns true if name is a header for this row, and false otherwise.

# File lib/csv.rb, line 479
def header?(name)
  headers.include? name
end
Also aliased as: include?
header_row?() click to toggle source

Returns true if this is a header row.

# File lib/csv.rb, line 256
def header_row?
  @header_row
end
headers() click to toggle source

Returns the headers of this row.

# File lib/csv.rb, line 266
def headers
  @row.map { |pair| pair.first }
end
include?(header) click to toggle source
Alias for: has_key?
index( header ) click to toggle source
index( header, offset )

This method will return the index of a field with the provided header. The offset can be used to locate duplicate header names, as described in #field.

# File lib/csv.rb, line 471
def index(header, minimum_index = 0)
  # find the pair
  index = headers[minimum_index..-1].index(header)
  # return the index at the right offset, if we found one
  index.nil? ? nil : index + minimum_index
end
inspect() click to toggle source

A summary of fields, by header, in an ASCII compatible String.

# File lib/csv.rb, line 537
def inspect
  str = ["#<", self.class.to_s]
  each do |header, field|
    str << " " << (header.is_a?(Symbol) ? header.to_s : header.inspect) <<
           ":" << field.inspect
  end
  str << ">"
  begin
    str.join('')
  rescue  # any encoding error
    str.map do |s|
      e = Encoding::Converter.asciicompat_encoding(s.encoding)
      e ? s.encode(e) : s.force_encoding("ASCII-8BIT")
    end.join('')
  end
end
key?(header) click to toggle source
Alias for: has_key?
member?(header) click to toggle source
Alias for: has_key?
push(*args) click to toggle source

A shortcut for appending multiple fields. Equivalent to:

args.each { |arg| csv_row << arg }

This method returns the row for chaining.

# File lib/csv.rb, line 394
def push(*args)
  args.each { |arg| self << arg }

  self  # for chaining
end
to_csv(options = Hash.new) click to toggle source

Returns the row as a CSV String. Headers are not used. Equivalent to:

csv_row.fields.to_csv( options )
# File lib/csv.rb, line 531
def to_csv(options = Hash.new)
  fields.to_csv(options)
end
Also aliased as: to_s
to_hash() click to toggle source

Collapses the row into a simple Hash. Be warning that this discards field order and clobbers duplicate fields.

# File lib/csv.rb, line 521
def to_hash
  # flatten just one level of the internal Array
  Hash[*@row.inject(Array.new) { |ary, pair| ary.push(*pair) }]
end
to_s(options = Hash.new) click to toggle source
Alias for: to_csv
values_at(*headers_and_or_indices) click to toggle source
Alias for: fields


class CSV::Table - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CSV::Table

A CSV::Table is a two-dimensional data structure for representing CSV documents. Tables allow you to work with the data by row or column, manipulate the data, and even convert the results back to CSV, if needed.

All tables returned by CSV will be constructed from this class, if header row processing is activated.

In Files

  • lib/csv.rb

Parent

Object

Included Modules

  • Enumerable

Attributes

mode[R]

The current access mode for indexing and iteration.

table[R]

Internal data format used to compare equality.

Public Class Methods

new(array_of_rows) click to toggle source

Construct a new CSV::Table from array_of_rows, which are expected to be CSV::Row objects. All rows are assumed to have the same headers.

A CSV::Table object supports the following Array methods through delegation:

  • empty?()

  • length()

  • size()

# File lib/csv.rb, line 575
def initialize(array_of_rows)
  @table = array_of_rows
  @mode  = :col_or_row
end

Public Instance Methods

<<(row_or_array) click to toggle source

Adds a new row to the bottom end of this table. You can provide an Array, which will be converted to a CSV::Row (inheriting the table's headers()), or a CSV::Row.

This method returns the table for chaining.

# File lib/csv.rb, line 773
def <<(row_or_array)
  if row_or_array.is_a? Array  # append Array
    @table << Row.new(headers, row_or_array)
  else                         # append Row
    @table << row_or_array
  end

  self  # for chaining
end
==(other) click to toggle source

Returns true if all rows of this table ==() other's rows.

# File lib/csv.rb, line 852
def ==(other)
  @table == other.table
end
[](index_or_header) click to toggle source

In the default mixed mode, this method returns rows for index access and columns for header access. You can force the index association by first calling #by_col!() or #by_row!().

Columns are returned as an Array of values. Altering that Array has no effect on the table.

# File lib/csv.rb, line 689
def [](index_or_header)
  if @mode == :row or  # by index
     (@mode == :col_or_row and index_or_header.is_a? Integer)
    @table[index_or_header]
  else                 # by header
    @table.map { |row| row[index_or_header] }
  end
end
[]=(index_or_header, value) click to toggle source

In the default mixed mode, this method assigns rows for index access and columns for header access. You can force the index association by first calling #by_col!() or #by_row!().

Rows may be set to an Array of values (which will inherit the table's headers()) or a CSV::Row.

Columns may be set to a single value, which is copied to each row of the column, or an Array of values. Arrays of values are assigned to rows top to bottom in row major order. Excess values are ignored and if the Array does not have a value for each row the extra rows will receive a nil.

Assigning to an existing column or row clobbers the data. Assigning to new columns creates them at the right end of the table.

# File lib/csv.rb, line 714
def []=(index_or_header, value)
  if @mode == :row or  # by index
     (@mode == :col_or_row and index_or_header.is_a? Integer)
    if value.is_a? Array
      @table[index_or_header] = Row.new(headers, value)
    else
      @table[index_or_header] = value
    end
  else                 # set column
    if value.is_a? Array  # multiple values
      @table.each_with_index do |row, i|
        if row.header_row?
          row[index_or_header] = index_or_header
        else
          row[index_or_header] = value[i]
        end
      end
    else                  # repeated value
      @table.each do |row|
        if row.header_row?
          row[index_or_header] = index_or_header
        else
          row[index_or_header] = value
        end
      end
    end
  end
end
by_col() click to toggle source

Returns a duplicate table object, in column mode. This is handy for chaining in a single call without changing the table mode, but be aware that this method can consume a fair amount of memory for bigger data sets.

This method returns the duplicate table for chaining. Don't chain destructive methods (like []=()) this way though, since you are working with a duplicate.

# File lib/csv.rb, line 601
def by_col
  self.class.new(@table.dup).by_col!
end
by_col!() click to toggle source

Switches the mode of this table to column mode. All calls to indexing and iteration methods will work with columns until the mode is changed again.

This method returns the table and is safe to chain.

# File lib/csv.rb, line 611
def by_col!
  @mode = :col

  self
end
by_col_or_row() click to toggle source

Returns a duplicate table object, in mixed mode. This is handy for chaining in a single call without changing the table mode, but be aware that this method can consume a fair amount of memory for bigger data sets.

This method returns the duplicate table for chaining. Don't chain destructive methods (like []=()) this way though, since you are working with a duplicate.

# File lib/csv.rb, line 626
def by_col_or_row
  self.class.new(@table.dup).by_col_or_row!
end
by_col_or_row!() click to toggle source

Switches the mode of this table to mixed mode. All calls to indexing and iteration methods will use the default intelligent indexing system until the mode is changed again. In mixed mode an index is assumed to be a row reference while anything else is assumed to be column access by headers.

This method returns the table and is safe to chain.

# File lib/csv.rb, line 638
def by_col_or_row!
  @mode = :col_or_row

  self
end
by_row() click to toggle source

Returns a duplicate table object, in row mode. This is handy for chaining in a single call without changing the table mode, but be aware that this method can consume a fair amount of memory for bigger data sets.

This method returns the duplicate table for chaining. Don't chain destructive methods (like []=()) this way though, since you are working with a duplicate.

# File lib/csv.rb, line 653
def by_row
  self.class.new(@table.dup).by_row!
end
by_row!() click to toggle source

Switches the mode of this table to row mode. All calls to indexing and iteration methods will work with rows until the mode is changed again.

This method returns the table and is safe to chain.

# File lib/csv.rb, line 663
def by_row!
  @mode = :row

  self
end
delete(index_or_header) click to toggle source

Removes and returns the indicated column or row. In the default mixed mode indices refer to rows and everything else is assumed to be a column header. Use #by_col!() or #by_row!() to force the lookup.

# File lib/csv.rb, line 801
def delete(index_or_header)
  if @mode == :row or  # by index
     (@mode == :col_or_row and index_or_header.is_a? Integer)
    @table.delete_at(index_or_header)
  else                 # by header
    @table.map { |row| row.delete(index_or_header).last }
  end
end
delete_if(&block) click to toggle source

Removes any column or row for which the block returns true. In the default mixed mode or row mode, iteration is the standard row major walking of rows. In column mode, interation will yield two element tuples containing the column name and an Array of values for that column.

This method returns the table for chaining.

# File lib/csv.rb, line 818
def delete_if(&block)
  if @mode == :row or @mode == :col_or_row  # by index
    @table.delete_if(&block)
  else                                      # by header
    to_delete = Array.new
    headers.each_with_index do |header, i|
      to_delete << header if block[[header, self[header]]]
    end
    to_delete.map { |header| delete(header) }
  end

  self  # for chaining
end
each(&block) click to toggle source

In the default mixed mode or row mode, iteration is the standard row major walking of rows. In column mode, interation will yield two element tuples containing the column name and an Array of values for that column.

This method returns the table for chaining.

# File lib/csv.rb, line 841
def each(&block)
  if @mode == :col
    headers.each { |header| block[[header, self[header]]] }
  else
    @table.each(&block)
  end

  self  # for chaining
end
headers() click to toggle source

Returns the headers for the first row of this table (assumed to match all other rows). An empty Array is returned for empty tables.

# File lib/csv.rb, line 673
def headers
  if @table.empty?
    Array.new
  else
    @table.first.headers
  end
end
inspect() click to toggle source

Shows the mode and size of this table in a US-ASCII String.

# File lib/csv.rb, line 890
def inspect
  "#<#{self.class} mode:#{@mode} row_count:#{to_a.size}>".encode("US-ASCII")
end
push(*rows) click to toggle source

A shortcut for appending multiple rows. Equivalent to:

rows.each { |row| self << row }

This method returns the table for chaining.

# File lib/csv.rb, line 790
def push(*rows)
  rows.each { |row| self << row }

  self  # for chaining
end
to_a() click to toggle source

Returns the table as an Array of Arrays. Headers will be the first row, then all of the field rows will follow.

# File lib/csv.rb, line 860
def to_a
  @table.inject([headers]) do |array, row|
    if row.header_row?
      array
    else
      array + [row.fields]
    end
  end
end
to_csv(options = Hash.new) click to toggle source

Returns the table as a complete CSV String. Headers will be listed first, then all of the field rows.

This method assumes you want the #headers, unless you explicitly pass :write_headers => false.

# File lib/csv.rb, line 877
def to_csv(options = Hash.new)
  wh = options.fetch(:write_headers, true)
  @table.inject(wh ? [headers.to_csv(options)] : [ ]) do |rows, row|
    if row.header_row?
      rows
    else
      rows + [row.fields.to_csv(options)]
    end
  end.join('')
end
Also aliased as: to_s
to_s(options = Hash.new) click to toggle source
Alias for: to_csv
values_at(*indices_or_headers) click to toggle source

The mixed mode default is to treat a list of indices as row access, returning the rows indicated. Anything else is considered columnar access. For columnar access, the return set has an Array for each row with the values indicated by the headers in each Array. You can force column or row mode using #by_col!() or #by_row!().

You cannot mix column and row access.

# File lib/csv.rb, line 752
def values_at(*indices_or_headers)
  if @mode == :row or  # by indices
     ( @mode == :col_or_row and indices_or_headers.all? do |index|
                                  index.is_a?(Integer)         or
                                  ( index.is_a?(Range)         and
                                    index.first.is_a?(Integer) and
                                    index.last.is_a?(Integer) )
                                end )
    @table.values_at(*indices_or_headers)
  else                 # by headers
    @table.map { |row| row.values_at(*indices_or_headers) }
  end
end


class Class - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Class

Extends any Class to include json_creatable? method.

In Files

  • ext/json/lib/json/common.rb

Parent

Object

Public Instance Methods

json_creatable?() click to toggle source

Returns true if this class can be used to create an instance from a serialised JSON string. The class has to implement a class method json_create that expects a hash as first parameter. The hash should include the required data.

# File ext/json/lib/json/common.rb, line 485
def json_creatable?
  respond_to?(:json_create)
end


class Complex - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Complex

In Files

  • ext/json/lib/json/add/complex.rb

Parent

Object

Public Class Methods

json_create(object) click to toggle source
# File ext/json/lib/json/add/complex.rb, line 7
def self.json_create(object)
  Complex(object['r'], object['i'])
end

Public Instance Methods

as_json(*) click to toggle source
# File ext/json/lib/json/add/complex.rb, line 11
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'r'            => real,
    'i'            => imag,
  }
end
to_json(*) click to toggle source
# File ext/json/lib/json/add/complex.rb, line 19
def to_json(*)
  as_json.to_json
end


class CompositePublisher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class CompositePublisher

Manage several publishers as a single entity.

In Files

  • lib/rake/contrib/publisher.rb

Parent

Object

Public Class Methods

new() click to toggle source
# File lib/rake/contrib/publisher.rb, line 19
def initialize
  @publishers = []
end

Public Instance Methods

add(pub) click to toggle source

Add a publisher to the composite.

# File lib/rake/contrib/publisher.rb, line 24
def add(pub)
  @publishers << pub
end
upload() click to toggle source

Upload all the individual publishers.

# File lib/rake/contrib/publisher.rb, line 29
def upload
  @publishers.each { |p| p.upload }
end


class ConditionVariable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class ConditionVariable

ConditionVariable objects augment class Mutex. Using condition variables, it is possible to suspend while in the middle of a critical section until a resource becomes available.

Example:

require 'thread'

mutex = Mutex.new
resource = ConditionVariable.new

a = Thread.new {
  mutex.synchronize {
    # Thread 'a' now needs the resource
    resource.wait(mutex)
    # 'a' can now have the resource
  }
}

b = Thread.new {
  mutex.synchronize {
    # Thread 'b' has finished using the resource
    resource.signal
  }
}

In Files

  • lib/thread.rb

Parent

Object

Public Class Methods

new() click to toggle source

Creates a new ConditionVariable

# File lib/thread.rb, line 54
def initialize
  @waiters = {}
  @waiters_mutex = Mutex.new
end

Public Instance Methods

broadcast() click to toggle source

Wakes up all threads waiting for this lock.

# File lib/thread.rb, line 101
def broadcast
  Thread.handle_interrupt(StandardError => :on_blocking) do
    threads = nil
    @waiters_mutex.synchronize do
      threads = @waiters.keys
      @waiters.clear
    end
    for t in threads
      begin
        t.run
      rescue ThreadError
      end
    end
  end
  self
end
signal() click to toggle source

Wakes up the first thread in line waiting for this lock.

# File lib/thread.rb, line 86
def signal
  Thread.handle_interrupt(StandardError => :on_blocking) do
    begin
      t, _ = @waiters_mutex.synchronize { @waiters.shift }
      t.run if t
    rescue ThreadError
      retry # t was already dead?
    end
  end
  self
end
wait(mutex, timeout=nil) click to toggle source

Releases the lock held in mutex and waits; reacquires the lock on wakeup.

If timeout is given, this method returns after timeout seconds passed, even if no other thread doesn't signal.

# File lib/thread.rb, line 65
def wait(mutex, timeout=nil)
  Thread.handle_interrupt(StandardError => :never) do
    begin
      Thread.handle_interrupt(StandardError => :on_blocking) do
        @waiters_mutex.synchronize do
          @waiters[Thread.current] = true
        end
        mutex.sleep timeout
      end
    ensure
      @waiters_mutex.synchronize do
        @waiters.delete(Thread.current)
      end
    end
  end
  self
end


module Coverage - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Coverage

Coverage provides coverage measurement feature for Ruby. This feature is experimental, so these APIs may be changed in future.

Usage

  1. require “coverage.so”

  2. do ::start

  3. require or load Ruby source file

  4. ::result will return a hash that contains filename as key and coverage array as value. A coverage array gives, for each line, the number of line execution by the interpreter. A nil value means coverage is disabled for this line (lines like else and end).

Example

[foo.rb]
s = 0
10.times do |x|
  s += x
end

if s == 45
  p :ok
else
  p :ng
end
[EOF]

require "coverage.so"
Coverage.start
require "foo.rb"
p Coverage.result  #=> {"foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]}

In Files

  • ext/coverage/coverage.c

Public Class Methods

result → hash click to toggle source

Returns a hash that contains filename as key and coverage array as value and disables coverage measurement.

static VALUE
rb_coverage_result(VALUE klass)
{
    VALUE coverages = rb_get_coverages();
    VALUE ncoverages = rb_hash_new();
    if (!RTEST(coverages)) {
        rb_raise(rb_eRuntimeError, "coverage measurement is not enabled");
    }
    st_foreach(RHASH_TBL(coverages), coverage_result_i, ncoverages);
    rb_hash_freeze(ncoverages);
    rb_reset_coverages();
    return ncoverages;
}
start → nil click to toggle source

Enables coverage measurement.

static VALUE
rb_coverage_start(VALUE klass)
{
    if (!RTEST(rb_get_coverages())) {
        if (rb_coverages == Qundef) {
            rb_coverages = rb_hash_new();
            RBASIC(rb_coverages)->klass = 0;
        }
        rb_set_coverages(rb_coverages);
    }
    return Qnil;
}


module Curses - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Curses

Description

An implementation of the CRT screen handling and optimization library.

Structures and such

Classes

  • Curses::Window - class with the means to draw a window or box

  • Curses::MouseEvent - class for collecting mouse events

Modules

Curses

The curses implementation

Curses::Key

Collection of constants for keypress events

Examples

  • hello.rb

    #!/usr/local/bin/ruby

require "curses"
include Curses

def show_message(message)
  width = message.length + 6
  win = Window.new(5, width,
               (lines - 5) / 2, (cols - width) / 2)
  win.box(|, -)
  win.setpos(2, 3)
  win.addstr(message)
  win.refresh
  win.getch
  win.close
end

init_screen
begin
  crmode
#  show_message("Hit any key")
  setpos((lines - 5) / 2, (cols - 10) / 2)
  addstr("Hit any key")
  refresh
  getch
  show_message("Hello, World!")
  refresh
ensure
  close_screen
end

  • rain.rb

    #!/usr/local/bin/ruby
# rain for a curses test

require "curses"
include Curses

def onsig(sig)
  close_screen
  exit sig
end

def ranf
  rand(32767).to_f / 32767
end

# main #
for i in %w[HUP INT QUIT TERM]
  if trap(i, "SIG_IGN") != 0 then  # 0 for SIG_IGN
    trap(i) {|sig| onsig(sig) }
  end
end

init_screen
nl
noecho
srand

xpos = {}
ypos = {}
r = lines - 4
c = cols - 4
for i in 0 .. 4
  xpos[i] = (c * ranf).to_i + 2
  ypos[i] = (r * ranf).to_i + 2
end

i = 0
while TRUE
  x = (c * ranf).to_i + 2
  y = (r * ranf).to_i + 2

  setpos(y, x); addstr(".")

  setpos(ypos[i], xpos[i]); addstr("o")

  i = if i == 0 then 4 else i - 1 end
  setpos(ypos[i], xpos[i]); addstr("O")

  i = if i == 0 then 4 else i - 1 end
  setpos(ypos[i] - 1, xpos[i]);      addstr("-")
  setpos(ypos[i],     xpos[i] - 1); addstr("|.|")
  setpos(ypos[i] + 1, xpos[i]);      addstr("-")

  i = if i == 0 then 4 else i - 1 end
  setpos(ypos[i] - 2, xpos[i]);       addstr("-")
  setpos(ypos[i] - 1, xpos[i] - 1);  addstr("/ \\")
  setpos(ypos[i],     xpos[i] - 2); addstr("| O |")
  setpos(ypos[i] + 1, xpos[i] - 1); addstr("\\ /")
  setpos(ypos[i] + 2, xpos[i]);       addstr("-")

  i = if i == 0 then 4 else i - 1 end
  setpos(ypos[i] - 2, xpos[i]);       addstr(" ")
  setpos(ypos[i] - 1, xpos[i] - 1);  addstr("   ")
  setpos(ypos[i],     xpos[i] - 2); addstr("     ")
  setpos(ypos[i] + 1, xpos[i] - 1);  addstr("   ")
  setpos(ypos[i] + 2, xpos[i]);       addstr(" ")

  xpos[i] = x
  ypos[i] = y
  refresh
  sleep(0.5)
end

# end of main

In Files

  • ext/curses/curses.c

Constants

ALL_MOUSE_EVENTS

report all button state changes

See ::getmouse

A_ALTCHARSET

Alternate character set

See ::attrset

A_ATTRIBUTES

Curses::Window#inch

A_BLINK

Blinking

See ::attrset

A_BOLD

Extra bright or bold

See ::attrset

A_CHARTEXT

Bit-mask to extract a character

See ::attrset

A_COLOR

Curses::Window#inch

A_DIM

Half bright

See ::attrset

A_HORIZONTAL

horizontal highlight

Check system curs_attr(3x) for support

A_INVIS

Invisible or blank mode

See ::attrset

A_LEFT

left highlight

Check system curs_attr(3x) for support

A_LOW

low highlight

Check system curs_attr(3x) for support

A_NORMAL

Normal display (no highlight)

See ::attrset

A_PROTECT

Protected mode

See ::attrset

A_REVERSE

Reverse video

See ::attrset

A_RIGHT

right highlight

Check system curs_attr(3x) for support

A_STANDOUT

Best highlighting mode of the terminal.

See ::attrset

A_TOP

top highlight

Check system curs_attr(3x) for support

A_UNDERLINE

Underlining

See ::attrset

A_VERTICAL

vertical highlight

Check system curs_attr(3x) for support

BUTTON1_CLICKED

mouse button 1 clicked

See ::getmouse

BUTTON1_DOUBLE_CLICKED

mouse button 1 double clicked

See ::getmouse

BUTTON1_PRESSED

mouse button 1 down

See ::getmouse

BUTTON1_RELEASED

mouse button 1 up

See ::getmouse

BUTTON1_TRIPLE_CLICKED

mouse button 1 triple clicked

See ::getmouse

BUTTON2_CLICKED

mouse button 2 clicked

See ::getmouse

BUTTON2_DOUBLE_CLICKED

mouse button 2 double clicked

See ::getmouse

BUTTON2_PRESSED

mouse button 2 down

See ::getmouse

BUTTON2_RELEASED

mouse button 2 up

See ::getmouse

BUTTON2_TRIPLE_CLICKED

mouse button 2 triple clicked

See ::getmouse

BUTTON3_CLICKED

mouse button 3 clicked

See ::getmouse

BUTTON3_DOUBLE_CLICKED

mouse button 3 double clicked

See ::getmouse

BUTTON3_PRESSED

mouse button 3 down

See ::getmouse

BUTTON3_RELEASED

mouse button 3 up

See ::getmouse

BUTTON3_TRIPLE_CLICKED

mouse button 3 triple clicked

See ::getmouse

BUTTON4_CLICKED

mouse button 4 clicked

See ::getmouse

BUTTON4_DOUBLE_CLICKED

mouse button 4 double clicked

See ::getmouse

BUTTON4_PRESSED

mouse button 4 down

See ::getmouse

BUTTON4_RELEASED

mouse button 4 up

See ::getmouse

BUTTON4_TRIPLE_CLICKED

mouse button 4 triple clicked

See ::getmouse

BUTTON_ALT

alt was down during button state change

See ::getmouse

BUTTON_CTRL

control was down during button state change

See ::getmouse

BUTTON_SHIFT

shift was down during button state change

See ::getmouse

COLORS

Number of the colors available

COLOR_BLACK

Value of the color black

COLOR_BLUE

Value of the color blue

COLOR_CYAN

Value of the color cyan

COLOR_GREEN

Value of the color green

COLOR_MAGENTA

Value of the color magenta

COLOR_RED

Value of the color red

COLOR_WHITE

Value of the color white

COLOR_YELLOW

Value of the color yellow

KEY_A1

Upper left of keypad

KEY_A3

Upper right of keypad

KEY_B2

Center of keypad

KEY_BACKSPACE

Backspace

KEY_BEG

Beginning key

KEY_BREAK

Break key

KEY_BTAB

Back tab key

KEY_C1

Lower left of keypad

KEY_C3

Lower right of keypad

KEY_CANCEL

Cancel key

KEY_CATAB

Clear all tabs

KEY_CLEAR

Clear Screen

KEY_CLOSE

Close key

KEY_COMMAND

Cmd (command) key

KEY_COPY

Copy key

KEY_CREATE

Create key

KEY_CTAB

Clear tab

KEY_DC

Delete character

KEY_DL

Delete line

KEY_DOWN

the down arrow key

KEY_EIC

Enter insert char mode

KEY_END

End key

KEY_ENTER

Enter or send

KEY_EOL

Clear to end of line

KEY_EOS

Clear to end of screen

KEY_EXIT

Exit key

KEY_FIND

Find key

KEY_HELP

Help key

KEY_HOME

Home key (upward+left arrow)

KEY_IC

Insert char or enter insert mode

KEY_IL

Insert line

KEY_LEFT

the left arrow key

KEY_LL

Home down or bottom (lower left)

KEY_MARK

Mark key

KEY_MAX

The maximum allowed curses key value.

KEY_MESSAGE

Message key

KEY_MIN

The minimum allowed curses key value.

KEY_MOUSE

Mouse event read

KEY_MOVE

Move key

KEY_NEXT

Next object key

KEY_NPAGE

Next page

KEY_OPEN

Open key

KEY_OPTIONS

Options key

KEY_PPAGE

Previous page

KEY_PREVIOUS

Previous object key

KEY_PRINT

Print or copy

KEY_REDO

Redo key

KEY_REFERENCE

Reference key

KEY_REFRESH

Refresh key

KEY_REPLACE

Replace key

KEY_RESET

Reset or hard reset

KEY_RESIZE

Screen Resized

KEY_RESTART

Restart key

KEY_RESUME

Resume key

KEY_RIGHT

the right arrow key

KEY_SAVE

Save key

KEY_SBEG

Shifted beginning key

KEY_SCANCEL

Shifted cancel key

KEY_SCOMMAND

Shifted command key

KEY_SCOPY

Shifted copy key

KEY_SCREATE

Shifted create key

KEY_SDC

Shifted delete char key

KEY_SDL

Shifted delete line key

KEY_SELECT

Select key

KEY_SEND

Shifted end key

KEY_SEOL

Shifted clear line key

KEY_SEXIT

Shifted exit key

KEY_SF

Scroll 1 line forward

KEY_SFIND

Shifted find key

KEY_SHELP

Shifted help key

KEY_SHOME

Shifted home key

KEY_SIC

Shifted input key

KEY_SLEFT

Shifted left arrow key

KEY_SMESSAGE

Shifted message key

KEY_SMOVE

Shifted move key

KEY_SNEXT

Shifted next key

KEY_SOPTIONS

Shifted options key

KEY_SPREVIOUS

Shifted previous key

KEY_SPRINT

Shifted print key

KEY_SR

Scroll 1 line backware (reverse)

KEY_SREDO

Shifted redo key

KEY_SREPLACE

Shifted replace key

KEY_SRESET

Soft (partial) reset

KEY_SRIGHT

Shifted right arrow key

KEY_SRSUME

Shifted resume key

KEY_SSAVE

Shifted save key

KEY_SSUSPEND

Shifted suspend key

KEY_STAB

Set tab

KEY_SUNDO

Shifted undo key

KEY_SUSPEND

Suspend key

KEY_UNDO

Undo key

KEY_UP

the up arrow key

REPORT_MOUSE_POSITION

report mouse movement

See ::getmouse

VERSION

Identifies curses library version.

  • “ncurses 5.9.20110404”

  • “PDCurses 3.4 - Public Domain 2008”

  • “curses (SVR4)” (System V curses)

  • “curses (unknown)” (The original BSD curses? NetBSD maybe.)

Public Class Methods

ESCDELAY() click to toggle source

Returns the total time, in milliseconds, for which curses will await a character sequence, e.g., a function key

static VALUE
curses_escdelay_get(VALUE obj)
{
    return INT2NUM(ESCDELAY);
}
ESCDELAY=(value) click to toggle source

Sets the ::ESCDELAY to Integer value

static VALUE
curses_escdelay_set(VALUE obj, VALUE val)
{
    ESCDELAY = NUM2INT(val);
    return INT2NUM(ESCDELAY);
}
TABSIZE() click to toggle source

Returns the number of positions in a tab.

static VALUE
curses_tabsize_get(VALUE ojb)
{
    return INT2NUM(TABSIZE);
}
TABSIZE=(value) click to toggle source

Sets the ::TABSIZE to Integer value

static VALUE
curses_tabsize_set(VALUE obj, VALUE val)
{
    TABSIZE = NUM2INT(val);
    return INT2NUM(TABSIZE);
}
addch(ch) click to toggle source

Add a character ch, with attributes, then advance the cursor.

see also the system manual for curs_addch(3)

static VALUE
curses_addch(VALUE obj, VALUE ch)
{
    curses_stdscr();
    addch(NUM2CH(ch));
    return Qnil;
}
addstr(str) click to toggle source

add a string of characters str, to the window and advance cursor

static VALUE
curses_addstr(VALUE obj, VALUE str)
{
    StringValue(str);
    str = rb_str_export_locale(str);
    curses_stdscr();
    if (!NIL_P(str)) {
        addstr(StringValueCStr(str));
    }
    return Qnil;
}
attroff(attrs) click to toggle source

Turns on the named attributes attrs without affecting any others.

See also Curses::Window#attrset for additional information.

static VALUE
curses_attroff(VALUE obj, VALUE attrs)
{
    curses_stdscr();
    return window_attroff(rb_stdscr,attrs);
    /* return INT2FIX(attroff(NUM2INT(attrs))); */
}
attron(attrs) click to toggle source

Turns off the named attributes attrs without turning any other attributes on or off.

See also Curses::Window#attrset for additional information.

static VALUE
curses_attron(VALUE obj, VALUE attrs)
{
    curses_stdscr();
    return window_attron(rb_stdscr,attrs);
    /* return INT2FIX(attroff(NUM2INT(attrs))); */
}
attrset(attrs) click to toggle source

Sets the current attributes of the given window to attrs.

see also Curses::Window#attrset

static VALUE
curses_attrset(VALUE obj, VALUE attrs)
{
    curses_stdscr();
    return window_attrset(rb_stdscr,attrs);
    /* return INT2FIX(attroff(NUM2INT(attrs))); */
}
beep() click to toggle source

Sounds an audible alarm on the terminal, if possible; otherwise it flashes the screen (visual bell).

see also ::flash

static VALUE
curses_beep(VALUE obj)
{
#ifdef HAVE_BEEP
    curses_stdscr();
    beep();
#endif
    return Qnil;
}
bkgd(ch) click to toggle source

Window background manipulation routines.

Set the background property of the current and then apply the character Integer ch setting to every character position in that window.

see also the system manual for curs_bkgd(3)

static VALUE
curses_bkgd(VALUE obj, VALUE ch)
{
#ifdef HAVE_BKGD
    curses_stdscr();
    return (bkgd(NUM2CH(ch)) == OK) ? Qtrue : Qfalse;
#else
    return Qfalse;
#endif
}
bkgdset(ch) click to toggle source

Manipulate the background of the named window with character Integer ch

The background becomes a property of the character and moves with the character through any scrolling and insert/delete line/character operations.

see also the system manual for curs_bkgd(3)

static VALUE
curses_bkgdset(VALUE obj, VALUE ch)
{
#ifdef HAVE_BKGDSET
    curses_stdscr();
    bkgdset(NUM2CH(ch));
#endif
    return Qnil;
}
can_change_color?() click to toggle source

Returns true or false depending on whether the terminal can change color attributes

static VALUE
curses_can_change_color(VALUE obj)
{
    curses_stdscr();
    return can_change_color() ? Qtrue : Qfalse;
}
cbreak() click to toggle source

Put the terminal into cbreak mode.

Normally, the tty driver buffers typed characters until a newline or carriage return is typed. The ::cbreak routine disables line buffering and erase/kill character-processing (interrupt and flow control characters are unaffected), making characters typed by the user immediately available to the program.

The ::nocbreak routine returns the terminal to normal (cooked) mode.

Initially the terminal may or may not be in cbreak mode, as the mode is inherited; therefore, a program should call ::cbreak or ::nocbreak explicitly. Most interactive programs using curses set the cbreak mode. Note that ::cbreak overrides ::raw.

see also ::raw

static VALUE
curses_cbreak(VALUE obj)
{
    curses_stdscr();
    cbreak();
    return Qnil;
}
clear() click to toggle source

Clears every position on the screen completely, so that a subsequent call by ::refresh for the screen/window will be repainted from scratch.

static VALUE
curses_clear(VALUE obj)
{
    curses_stdscr();
    wclear(stdscr);
    return Qnil;
}
close_screen() click to toggle source

A program should always call ::close_screen before exiting or escaping from curses mode temporarily. This routine restores tty modes, moves the cursor to the lower left-hand corner of the screen and resets the terminal into the proper non-visual mode.

Calling ::refresh or ::doupdate after a temporary escape causes the program to resume visual mode.

static VALUE
curses_close_screen(void)
{
    curses_stdscr();
#ifdef HAVE_ISENDWIN
    if (!isendwin())
#endif
        endwin();
    rb_stdscr = 0;
    return Qnil;
}
closed?() click to toggle source

Returns true if the window/screen has been closed, without any subsequent ::refresh calls, returns false otherwise.

static VALUE
curses_closed(void)
{
    curses_stdscr();
    if (isendwin()) {
        return Qtrue;
    }
    return Qfalse;
}
clrtoeol() click to toggle source

Clears to the end of line, that the cursor is currently on.

static VALUE
curses_clrtoeol(void)
{
    curses_stdscr();
    clrtoeol();
    return Qnil;
}
color_content(color) click to toggle source

Returns an 3 item Array of the RGB values in color

static VALUE
curses_color_content(VALUE obj, VALUE color)
{
    short r,g,b;

    curses_stdscr();
    color_content(NUM2INT(color),&r,&g,&b);
    return rb_ary_new3(3,INT2FIX(r),INT2FIX(g),INT2FIX(b));
}
color_pair(attrs) click to toggle source

Sets the color pair attributes to attrs.

This should be equivalent to ::attrset(COLOR_PAIR(attrs))

TODO: validate that equivalency

static VALUE
curses_color_pair(VALUE obj, VALUE attrs)
{
    return INT2FIX(COLOR_PAIR(NUM2INT(attrs)));
}
color_pairs() click to toggle source

Returns the COLOR_PAIRS available, if the curses library supports it.

static VALUE
curses_color_pairs(VALUE obj)
{
    return INT2FIX(COLOR_PAIRS);
}
colors() click to toggle source

returns COLORS

static VALUE
curses_colors(VALUE obj)
{
    return INT2FIX(COLORS);
}
cols() click to toggle source

Returns the number of columns on the screen

static VALUE
curses_cols(void)
{
    return INT2FIX(COLS);
}
crmode() click to toggle source

Put the terminal into cbreak mode.

Normally, the tty driver buffers typed characters until a newline or carriage return is typed. The ::cbreak routine disables line buffering and erase/kill character-processing (interrupt and flow control characters are unaffected), making characters typed by the user immediately available to the program.

The ::nocbreak routine returns the terminal to normal (cooked) mode.

Initially the terminal may or may not be in cbreak mode, as the mode is inherited; therefore, a program should call ::cbreak or ::nocbreak explicitly. Most interactive programs using curses set the cbreak mode. Note that ::cbreak overrides ::raw.

see also ::raw

static VALUE
curses_cbreak(VALUE obj)
{
    curses_stdscr();
    cbreak();
    return Qnil;
}
curs_set(visibility) click to toggle source

Sets Cursor Visibility. 0: invisible 1: visible 2: very visible

static VALUE
curses_curs_set(VALUE obj, VALUE visibility)
{
#ifdef HAVE_CURS_SET
    int n;
    curses_stdscr();
    return (n = curs_set(NUM2INT(visibility)) != ERR) ? INT2FIX(n) : Qnil;
#else
    return Qnil;
#endif
}
def_prog_mode() click to toggle source

Save the current terminal modes as the “program” state for use by the ::reset_prog_mode

This is done automatically by ::init_screen

static VALUE
curses_def_prog_mode(VALUE obj)
{
    curses_stdscr();
    return def_prog_mode() == OK ? Qtrue : Qfalse;
}
delch() click to toggle source

Delete the character under the cursor

static VALUE
curses_delch(VALUE obj)
{
    curses_stdscr();
    delch();
    return Qnil;
}
deleteln() click to toggle source

Delete the line under the cursor.

static VALUE
curses_deleteln(VALUE obj)
{
    curses_stdscr();
#if defined(HAVE_DELETELN) || defined(deleteln)
    deleteln();
#endif
    return Qnil;
}
doupdate() click to toggle source

Refreshes the windows and lines.

::doupdate allows multiple updates with more efficiency than ::refresh alone.

static VALUE
curses_doupdate(VALUE obj)
{
    curses_stdscr();
#ifdef HAVE_DOUPDATE
    doupdate();
#else
    refresh();
#endif
    return Qnil;
}
echo() click to toggle source

Enables characters typed by the user to be echoed by ::getch as they are typed.

static VALUE
curses_echo(VALUE obj)
{
    curses_stdscr();
    echo();
    return Qnil;
}
flash() click to toggle source

Flashs the screen, for visual alarm on the terminal, if possible; otherwise it sounds the alert.

see also ::beep

static VALUE
curses_flash(VALUE obj)
{
#ifdef HAVE_FLASH
    curses_stdscr();
    flash();
#endif
    return Qnil;
}
getch() click to toggle source

Read and returns a character from the window.

See Curses::Key to all the function KEY_* available

static VALUE
curses_getch(VALUE obj)
{
    int c;

    curses_stdscr();
    rb_thread_call_without_gvl(getch_func, &c, RUBY_UBF_IO, 0);
    if (c == EOF) return Qnil;
    if (rb_isprint(c)) {
        char ch = (char)c;

        return rb_locale_str_new(&ch, 1);
    }
    return UINT2NUM(c);
}
getmouse() click to toggle source

Returns coordinates of the mouse.

This will read and pop the mouse event data off the queue

See the BUTTON*, ALL_MOUSE_EVENTS and REPORT_MOUSE_POSITION constants, to examine the mask of the event

static VALUE
curses_getmouse(VALUE obj)
{
    struct mousedata *mdata;
    VALUE val;

    curses_stdscr();
    val = TypedData_Make_Struct(cMouseEvent,struct mousedata,
                                &mousedata_type,mdata);
    mdata->mevent = (MEVENT*)xmalloc(sizeof(MEVENT));
    return (getmouse(mdata->mevent) == OK) ? val : Qnil;
}
getstr() click to toggle source

This is equivalent to a series f Curses::Window#getch calls

static VALUE
curses_getstr(VALUE obj)
{
    char rtn[GETSTR_BUF_SIZE];

    curses_stdscr();
    rb_thread_call_without_gvl(getstr_func, rtn, RUBY_UBF_IO, 0);
    return rb_locale_str_new_cstr(rtn);
}
has_colors?() click to toggle source

Returns true or false depending on whether the terminal has color capbilities.

static VALUE
curses_has_colors(VALUE obj)
{
    curses_stdscr();
    return has_colors() ? Qtrue : Qfalse;
}
inch() click to toggle source

Returns the character at the current position.

static VALUE
curses_inch(VALUE obj)
{
    curses_stdscr();
    return CH2FIX(inch());
}
init_color(color, r, g, b) click to toggle source

Changes the definition of a color. It takes four arguments:

  • the number of the color to be changed, color

  • the amount of red, r

  • the amount of green, g

  • the amount of blue, b

The value of the first argument must be between 0 and COLORS. (See the section Colors for the default color index.) Each of the last three arguments must be a value between 0 and 1000. When ::init_color is used, all occurrences of that color on the screen immediately change to the new definition.

static VALUE
curses_init_color(VALUE obj, VALUE color, VALUE r, VALUE g, VALUE b)
{
    /* may have to raise exception on ERR */
    curses_stdscr();
    return (init_color(NUM2INT(color),NUM2INT(r),
                       NUM2INT(g),NUM2INT(b)) == OK) ? Qtrue : Qfalse;
}
init_pair(pair, f, b) click to toggle source

Changes the definition of a color-pair.

It takes three arguments: the number of the color-pair to be changed pair, the foreground color number f, and the background color number b.

If the color-pair was previously initialized, the screen is refreshed and all occurrences of that color-pair are changed to the new definition.

static VALUE
curses_init_pair(VALUE obj, VALUE pair, VALUE f, VALUE b)
{
    /* may have to raise exception on ERR */
    curses_stdscr();
    return (init_pair(NUM2INT(pair),NUM2INT(f),NUM2INT(b)) == OK) ? Qtrue : Qfalse;
}
init_screen() click to toggle source

Initialize a standard screen

see also ::stdscr

static VALUE
curses_init_screen(void)
{
    rb_secure(4);
    if (rb_stdscr) return rb_stdscr;
    initscr();
    if (stdscr == 0) {
        rb_raise(rb_eRuntimeError, "can't initialize curses");
    }
    clear();
    rb_stdscr = prep_window(cWindow, stdscr);
    return rb_stdscr;
}
insch(ch) click to toggle source

Insert a character ch, before the cursor.

static VALUE
curses_insch(VALUE obj, VALUE ch)
{
    curses_stdscr();
    insch(NUM2CH(ch));
    return Qnil;
}
insertln() click to toggle source

Inserts a line above the cursor, and the bottom line is lost

static VALUE
curses_insertln(VALUE obj)
{
    curses_stdscr();
#if defined(HAVE_INSERTLN) || defined(insertln)
    insertln();
#endif
    return Qnil;
}
keyname(c) click to toggle source

Returns the character string corresponding to key c

static VALUE
curses_keyname(VALUE obj, VALUE c)
{
#ifdef HAVE_KEYNAME
    int cc = curses_char(c);
    const char *name;

    curses_stdscr();
    name = keyname(cc);
    if (name) {
        return rb_str_new_cstr(name);
    }
    else {
        return Qnil;
    }
#else
    return Qnil;
#endif
}
lines() click to toggle source

Returns the number of lines on the screen

static VALUE
curses_lines(void)
{
    return INT2FIX(LINES);
}
mouseinterval(interval) click to toggle source

The ::mouseinterval function sets the maximum time (in thousands of a second) that can elapse between press and release events for them to be recognized as a click.

Use ::mouseinterval to disable click resolution. This function returns the previous interval value.

Use ::mouseinterval to obtain the interval without altering it.

The default is one sixth of a second.

static VALUE
curses_mouseinterval(VALUE obj, VALUE interval)
{
    curses_stdscr();
    return mouseinterval(NUM2INT(interval)) ? Qtrue : Qfalse;
}
mousemask(mask) click to toggle source

Returns the mask of the reportable events

static VALUE
curses_mousemask(VALUE obj, VALUE mask)
{
    curses_stdscr();
    return INT2NUM(mousemask(NUM2UINT(mask),NULL));
}
nl() click to toggle source

Enable the underlying display device to translate the return key into newline on input, and whether it translates newline into return and line-feed on output (in either case, the call ::addch('n') does the equivalent of return and line feed on the virtual screen).

Initially, these translations do occur. If you disable them using ::nonl, curses will be able to make better use of the line-feed capability, resulting in faster cursor motion. Also, curses will then be able to detect the return key.

static VALUE
curses_nl(VALUE obj)
{
    curses_stdscr();
    nl();
    return Qnil;
}
nocbreak() click to toggle source

Put the terminal into normal mode (out of cbreak mode).

See ::cbreak for more detail.

static VALUE
curses_nocbreak(VALUE obj)
{
    curses_stdscr();
    nocbreak();
    return Qnil;
}
nocrmode() click to toggle source

Put the terminal into normal mode (out of cbreak mode).

See ::cbreak for more detail.

static VALUE
curses_nocbreak(VALUE obj)
{
    curses_stdscr();
    nocbreak();
    return Qnil;
}
noecho() click to toggle source

Disables characters typed by the user to be echoed by ::getch as they are typed.

static VALUE
curses_noecho(VALUE obj)
{
    curses_stdscr();
    noecho();
    return Qnil;
}
nonl() click to toggle source

Disable the underlying display device to translate the return key into newline on input

See ::nl for more detail

static VALUE
curses_nonl(VALUE obj)
{
    curses_stdscr();
    nonl();
    return Qnil;
}
noraw() click to toggle source

Put the terminal out of raw mode.

see ::raw for more detail

static VALUE
curses_noraw(VALUE obj)
{
    curses_stdscr();
    noraw();
    return Qnil;
}
pair_content(pair) click to toggle source

Returns a 2 item Array, with the foreground and background color, in pair

static VALUE
curses_pair_content(VALUE obj, VALUE pair)
{
    short f,b;

    curses_stdscr();
    pair_content(NUM2INT(pair),&f,&b);
    return rb_ary_new3(2,INT2FIX(f),INT2FIX(b));
}
pair_number(attrs) click to toggle source

Returns the Fixnum color pair number of attributes attrs.

static VALUE
curses_pair_number(VALUE obj, VALUE attrs)
{
    curses_stdscr();
    return INT2FIX(PAIR_NUMBER(NUM2LONG(attrs)));
}
raw() click to toggle source

Put the terminal into raw mode.

Raw mode is similar to ::cbreak mode, in that characters typed are immediately passed through to the user program.

The differences are that in raw mode, the interrupt, quit, suspend, and flow control characters are all passed through uninterpreted, instead of generating a signal. The behavior of the BREAK key depends on other bits in the tty driver that are not set by curses.

static VALUE
curses_raw(VALUE obj)
{
    curses_stdscr();
    raw();
    return Qnil;
}
refresh() click to toggle source

Refreshes the windows and lines.

static VALUE
curses_refresh(VALUE obj)
{
    curses_stdscr();
    refresh();
    return Qnil;
}
reset_prog_mode() click to toggle source

Reset the current terminal modes to the saved state by the ::def_prog_mode

This is done automatically by ::close_screen

static VALUE
curses_reset_prog_mode(VALUE obj)
{
    curses_stdscr();
    return reset_prog_mode() == OK ? Qtrue : Qfalse;
}
resizeterm(lines, cols) click to toggle source

Resize the current term to Fixnum lines and Fixnum cols

static VALUE
curses_resizeterm(VALUE obj, VALUE lin, VALUE col)
{
#if defined(HAVE_RESIZETERM)
    curses_stdscr();
    return (resizeterm(NUM2INT(lin),NUM2INT(col)) == OK) ? Qtrue : Qfalse;
#else
    return Qnil;
#endif
}
resizeterm(lines, cols) click to toggle source

Resize the current term to Fixnum lines and Fixnum cols

static VALUE
curses_resizeterm(VALUE obj, VALUE lin, VALUE col)
{
#if defined(HAVE_RESIZETERM)
    curses_stdscr();
    return (resizeterm(NUM2INT(lin),NUM2INT(col)) == OK) ? Qtrue : Qfalse;
#else
    return Qnil;
#endif
}
scrl(num) click to toggle source

Scrolls the current window Fixnum num lines. The current cursor position is not changed.

For positive num, it scrolls up.

For negative num, it scrolls down.

static VALUE
curses_scrl(VALUE obj, VALUE n)
{
    /* may have to raise exception on ERR */
#ifdef HAVE_SCRL
    curses_stdscr();
    return (scrl(NUM2INT(n)) == OK) ? Qtrue : Qfalse;
#else
    return Qfalse;
#endif
}
setpos(y, x) click to toggle source

A setter for the position of the cursor, using coordinates x and y

static VALUE
curses_setpos(VALUE obj, VALUE y, VALUE x)
{
    curses_stdscr();
    move(NUM2INT(y), NUM2INT(x));
    return Qnil;
}
setscrreg(top, bottom) click to toggle source

Set a software scrolling region in a window. top and bottom are lines numbers of the margin.

If this option and Curses.scrollok are enabled, an attempt to move off the bottom margin line causes all lines in the scrolling region to scroll one line in the direction of the first line. Only the text of the window is scrolled.

static VALUE
curses_setscrreg(VALUE obj, VALUE top, VALUE bottom)
{
    /* may have to raise exception on ERR */
#ifdef HAVE_SETSCRREG
    curses_stdscr();
    return (setscrreg(NUM2INT(top), NUM2INT(bottom)) == OK) ? Qtrue : Qfalse;
#else
    return Qfalse;
#endif
}
standend() click to toggle source

Enables the Normal display (no highlight)

This is equivalent to ::attron

see also Curses::Window#attrset for additional information.

static VALUE
curses_standend(VALUE obj)
{
    curses_stdscr();
    standend();
    return Qnil;
}
standout() click to toggle source

Enables the best highlighting mode of the terminal.

This is equivalent to Curses:Curses::Window#attron

see also Curses::Window#attrset additional information

static VALUE
curses_standout(VALUE obj)
{
    curses_stdscr();
    standout();
    return Qnil;
}
start_color() click to toggle source

Initializes the color attributes, for terminals that support it.

This must be called, in order to use color attributes. It is good practice to call it just after ::init_screen

static VALUE
curses_start_color(VALUE obj)
{
    /* may have to raise exception on ERR */
    curses_stdscr();
    return (start_color() == OK) ? Qtrue : Qfalse;
}
stdscr() click to toggle source

The Standard Screen.

Upon initializing curses, a default window called stdscr, which is the size of the terminal screen, is created.

Many curses functions use this window.

#define curses_stdscr curses_init_screen
timeout=(delay) click to toggle source

Sets block and non-blocking reads for the window.

  • If delay is negative, blocking read is used (i.e., waits indefinitely for input).

  • If delay is zero, then non-blocking read is used (i.e., read returns ERR if no input is waiting).

  • If delay is positive, then read blocks for delay milliseconds, and returns ERR if there is still no input.

static VALUE
curses_timeout(VALUE obj, VALUE delay)
{
    curses_stdscr();
    timeout(NUM2INT(delay));
    return Qnil;
}
ungetch(ch) click to toggle source

Places ch back onto the input queue to be returned by the next call to ::getch.

There is just one input queue for all windows.

static VALUE
curses_ungetch(VALUE obj, VALUE ch)
{
    int c = curses_char(ch);
    curses_stdscr();
    ungetch(c);
    return Qnil;
}
ungetmouse(p1) click to toggle source

It pushes a KEY_MOUSE event onto the input queue, and associates with that event the given state data and screen-relative character-cell coordinates.

The ::ungetmouse function behaves analogously to ::ungetch.

static VALUE
curses_ungetmouse(VALUE obj, VALUE mevent)
{
    struct mousedata *mdata;

    curses_stdscr();
    GetMOUSE(mevent,mdata);
    return (ungetmouse(mdata->mevent) == OK) ? Qtrue : Qfalse;
}
use_default_colors() click to toggle source

tells the curses library to use terminal's default colors.

see also the system manual for default_colors(3)

static VALUE
curses_use_default_colors(VALUE obj)
{
    curses_stdscr();
    use_default_colors();
    return Qnil;
}


module Curses::Key - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Curses::Key

a container for the KEY_* values.

See also system manual for getch(3)

In Files

  • ext/curses/curses.c

Constants

A1

Upper left of keypad

A3

Upper right of keypad

B2

Center of keypad

BACKSPACE

Backspace

BEG

Beginning key

BREAK

Break key

BTAB

Back tab key

C1

Lower left of keypad

C3

Lower right of keypad

CANCEL

Cancel key

CATAB

Clear all tabs

CLEAR

Clear Screen

CLOSE

Close key

COMMAND

Cmd (command) key

COPY

Copy key

CREATE

Create key

CTAB

Clear tab

DC

Delete character

DL

Delete line

DOWN

the down arrow key

EIC

Enter insert char mode

END

End key

ENTER

Enter or send

EOL

Clear to end of line

EOS

Clear to end of screen

EXIT

Exit key

FIND

Find key

HELP

Help key

HOME

Home key (upward+left arrow)

IC

Insert char or enter insert mode

IL

Insert line

LEFT

the left arrow key

LL

Home down or bottom (lower left)

MARK

Mark key

MAX

The maximum allowed curses key value.

MESSAGE

Message key

MIN

The minimum allowed curses key value.

MOUSE

Mouse event read

MOVE

Move key

NEXT

Next object key

NPAGE

Next page

OPEN

Open key

OPTIONS

Options key

PPAGE

Previous page

PREVIOUS

Previous object key

PRINT

Print or copy

REDO

Redo key

REFERENCE

Reference key

REFRESH

Refresh key

REPLACE

Replace key

RESET

Reset or hard reset

RESIZE

Screen Resized

RESTART

Restart key

RESUME

Resume key

RIGHT

the right arrow key

SAVE

Save key

SBEG

Shifted beginning key

SCANCEL

Shifted cancel key

SCOMMAND

Shifted command key

SCOPY

Shifted copy key

SCREATE

Shifted create key

SDC

Shifted delete char key

SDL

Shifted delete line key

SELECT

Select key

SEND

Shifted end key

SEOL

Shifted clear line key

SEXIT

Shifted exit key

SF

Scroll 1 line forward

SFIND

Shifted find key

SHELP

Shifted help key

SHOME

Shifted home key

SIC

Shifted input key

SLEFT

Shifted left arrow key

SMESSAGE

Shifted message key

SMOVE

Shifted move key

SNEXT

Shifted next key

SOPTIONS

Shifted options key

SPREVIOUS

Shifted previous key

SPRINT

Shifted print key

SR

Scroll 1 line backware (reverse)

SREDO

Shifted redo key

SREPLACE

Shifted replace key

SRESET

Soft (partial) reset

SRIGHT

Shifted right arrow key

SRSUME

Shifted resume key

SSAVE

Shifted save key

SSUSPEND

Shifted suspend key

STAB

Set tab

SUNDO

Shifted undo key

SUSPEND

Suspend key

UNDO

Undo key

UP

the up arrow key


class Curses::MouseEvent - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Curses::MouseEvent

Description

Curses::MouseEvent

Example

  • mouse.rb

    #!/usr/local/bin/ruby

require "curses"
include Curses

def show_message(*msgs)
  message = msgs.join
  width = message.length + 6
  win = Window.new(5, width,
               (lines - 5) / 2, (cols - width) / 2)
  win.keypad = true
  win.attron(color_pair(COLOR_RED)){
    win.box(|, -, +)
  }
  win.setpos(2, 3)
  win.addstr(message)
  win.refresh
  win.getch
  win.close
end

init_screen
start_color
init_pair(COLOR_BLUE,COLOR_BLUE,COLOR_WHITE)
init_pair(COLOR_RED,COLOR_RED,COLOR_WHITE)
crmode
noecho
stdscr.keypad(true)

begin
  mousemask(BUTTON1_CLICKED|BUTTON2_CLICKED|BUTTON3_CLICKED|BUTTON4_CLICKED)
  setpos((lines - 5) / 2, (cols - 10) / 2)
  attron(color_pair(COLOR_BLUE)|A_BOLD){
    addstr("click")
  }
  refresh
  while( true )
    c = getch
    case c
    when KEY_MOUSE
      m = getmouse
      if( m )
    show_message("getch = #{c.inspect}, ",
                 "mouse event = #{'0x%x' % m.bstate}, ",
                 "axis = (#{m.x},#{m.y},#{m.z})")
      end
      break
    end
  end
  refresh
ensure
  close_screen
end

In Files

  • ext/curses/curses.c

Parent

Object


class Curses::Pad - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Curses::Pad

Description

A Pad is like a Window but allows for scrolling of contents that cannot fit on the screen. Pads do not refresh automatically, use #refresh or #noutrefresh instead.

In Files

  • ext/curses/curses.c

Parent

Curses::Window

Public Class Methods

new(height, width) click to toggle source

Contruct a new Curses::Pad with constraints of height lines, width columns

static VALUE
pad_initialize(VALUE obj, VALUE h, VALUE w)
{
    struct windata *padp;
    WINDOW *window;

    rb_secure(4);
    curses_init_screen();
    TypedData_Get_Struct(obj, struct windata, &windata_type, padp);
    if (padp->window) delwin(padp->window);
    window = newpad(NUM2INT(h), NUM2INT(w));
    wclear(window);
    padp->window = window;

    return obj;
}

Public Instance Methods

noutrefresh(pad_minrow, pad_mincol, screen_minrow, screen_mincol, screen_maxrow, screen_maxcol) click to toggle source

Refreshes the pad. pad_minrow and pad_mincol+ define the upper-left corner of the rectangle to be displayed. screen_minrow, screen_mincol, screen_maxrow, screen_maxcol define the edges of the rectangle to be displayed on the screen.

static VALUE
pad_noutrefresh(VALUE obj, VALUE pminrow, VALUE pmincol, VALUE sminrow,
                VALUE smincol, VALUE smaxrow, VALUE smaxcol)
{
    struct windata *padp;
    int pmr, pmc, smr, smc, sxr, sxc;

    pmr = NUM2INT(pminrow);
    pmc = NUM2INT(pmincol);
    smr = NUM2INT(sminrow);
    smc = NUM2INT(smincol);
    sxr = NUM2INT(smaxrow);
    sxc = NUM2INT(smaxcol);

    GetWINDOW(obj, padp);
#ifdef HAVE_DOUPDATE
    pnoutrefresh(padp->window, pmr, pmc, smr, smc, sxr, sxc);
#else
    prefresh(padp->window, pmr, pmc, smr, smc, sxr, sxc);
#endif

    return Qnil;
}
refresh(pad_minrow, pad_mincol, screen_minrow, screen_mincol, screen_maxrow, screen_maxcol) click to toggle source

Refreshes the pad. pad_minrow and pad_mincol+ define the upper-left corner of the rectangle to be displayed. screen_minrow, screen_mincol, screen_maxrow, screen_maxcol define the edges of the rectangle to be displayed on the screen.

static VALUE
pad_refresh(VALUE obj, VALUE pminrow, VALUE pmincol, VALUE sminrow,
            VALUE smincol, VALUE smaxrow, VALUE smaxcol)
{
    struct windata *padp;
    int pmr, pmc, smr, smc, sxr, sxc;

    pmr = NUM2INT(pminrow);
    pmc = NUM2INT(pmincol);
    smr = NUM2INT(sminrow);
    smc = NUM2INT(smincol);
    sxr = NUM2INT(smaxrow);
    sxc = NUM2INT(smaxcol);

    GetWINDOW(obj, padp);
    prefresh(padp->window, pmr, pmc, smr, smc, sxr, sxc);

    return Qnil;
}
subpad(height, width, begin_x, begin_y) click to toggle source

Contruct a new subpad with constraints of height lines, width columns, begin at begin_x line, and begin_y columns on the pad.

static VALUE
pad_subpad(VALUE obj, VALUE height, VALUE width, VALUE begin_x, VALUE begin_y)
{
    struct windata *padp;
    WINDOW *subpad;
    VALUE pad;
    int h, w, x, y;

    h = NUM2INT(height);
    w = NUM2INT(width);
    x = NUM2INT(begin_x);
    y = NUM2INT(begin_y);
    GetWINDOW(obj, padp);
    subpad = subwin(padp->window, h, w, x, y);
    pad = prep_window(rb_obj_class(obj), subpad);

    return pad;
}


class Curses::Window - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Curses::Window

Description

The means by which to create and manage frames or windows. While there may be more than one window at a time, only one window will receive input.

Usage

require 'curses'

Curses.init_screen()

my_str = "LOOK! PONIES!"
win = Curses::Window.new( 8, (my_str.length + 10),
                          (Curses.lines - 8) / 2,
                          (Curses.cols - (my_str.length + 10)) / 2 )
win.box("|", "-")
win.setpos(2,3)
win.addstr(my_str)
# or even
win << "\nORLY"
win << "\nYES!! " + my_str
win.refresh
win.getch
win.close

In Files

  • ext/curses/curses.c

Parent

Data

Public Class Methods

new(height, width, top, left) click to toggle source

Contruct a new Curses::Window with constraints of height lines, width columns, begin at top line, and begin left most column.

A new window using full screen is called as

Curses::Window.new(0,0,0,0)
static VALUE
window_initialize(VALUE obj, VALUE h, VALUE w, VALUE top, VALUE left)
{
    struct windata *winp;
    WINDOW *window;

    rb_secure(4);
    curses_init_screen();
    TypedData_Get_Struct(obj, struct windata, &windata_type, winp);
    if (winp->window) delwin(winp->window);
    window = newwin(NUM2INT(h), NUM2INT(w), NUM2INT(top), NUM2INT(left));
    wclear(window);
    winp->window = window;

    return obj;
}

Public Instance Methods

<<(str) click to toggle source

<<

Add String str to the current string.

See also #addstr

static VALUE
window_addstr2(VALUE obj, VALUE str)
{
    window_addstr(obj, str);
    return obj;
}
addch(ch) click to toggle source

Add a character ch, with attributes, to the window, then advance the cursor.

see also the system manual for curs_addch(3)

static VALUE
window_addch(VALUE obj, VALUE ch)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    waddch(winp->window, NUM2CH(ch));

    return Qnil;
}
addstr(str) click to toggle source

add a string of characters str, to the window and advance cursor

static VALUE
window_addstr(VALUE obj, VALUE str)
{
    if (!NIL_P(str)) {
        struct windata *winp;

        StringValue(str);
        str = rb_str_export_locale(str);
        GetWINDOW(obj, winp);
        waddstr(winp->window, StringValueCStr(str));
    }
    return Qnil;
}
attroff(attrs) click to toggle source

Turns on the named attributes attrs without affecting any others.

See also #attrset

static VALUE
window_attroff(VALUE obj, VALUE attrs)
{
#ifdef HAVE_WATTROFF
    struct windata *winp;

    GetWINDOW(obj,winp);
    return INT2FIX(wattroff(winp->window,NUM2INT(attrs)));
#else
    return Qtrue;
#endif
}
attron(attrs) click to toggle source

Turns off the named attributes attrs without turning any other attributes on or off.

See also #attrset

static VALUE
window_attron(VALUE obj, VALUE attrs)
{
#ifdef HAVE_WATTRON
    struct windata *winp;
    VALUE val;

    GetWINDOW(obj,winp);
    val = INT2FIX(wattron(winp->window,NUM2INT(attrs)));
    if (rb_block_given_p()) {
        rb_yield(val);
        wattroff(winp->window,NUM2INT(attrs));
        return val;
    }
    else{
        return val;
    }
#else
    return Qtrue;
#endif
}
attrset(attrs) click to toggle source

Sets the current attributes of the given window to attrs.

The following video attributes, defined in <curses.h>, can be passed to the routines #attron, #attroff, and #attrset, or OR'd with the characters passed to addch.

A_NORMAL        Normal display (no highlight)
A_STANDOUT      Best highlighting mode of the terminal.
A_UNDERLINE     Underlining
A_REVERSE       Reverse video
A_BLINK         Blinking
A_DIM           Half bright
A_BOLD          Extra bright or bold
A_PROTECT       Protected mode
A_INVIS         Invisible or blank mode
A_ALTCHARSET    Alternate character set
A_CHARTEXT      Bit-mask to extract a character
COLOR_PAIR(n)   Color-pair number n

TODO: provide some examples here.

see also system manual curs_attr(3)

static VALUE
window_attrset(VALUE obj, VALUE attrs)
{
#ifdef HAVE_WATTRSET
    struct windata *winp;

    GetWINDOW(obj,winp);
    return INT2FIX(wattrset(winp->window,NUM2INT(attrs)));
#else
    return Qtrue;
#endif
}
begx() click to toggle source

A getter for the beginning column (X coord) of the window

static VALUE
window_begx(VALUE obj)
{
    struct windata *winp;
    int x, RB_UNUSED_VAR(y);

    GetWINDOW(obj, winp);
#ifdef getbegyx
    getbegyx(winp->window, y, x);
#else
    x = winp->window->_begx;
#endif
    return INT2FIX(x);
}
begy() click to toggle source

A getter for the beginning line (Y coord) of the window

static VALUE
window_begy(VALUE obj)
{
    struct windata *winp;
    int RB_UNUSED_VAR(x), y;

    GetWINDOW(obj, winp);
#ifdef getbegyx
    getbegyx(winp->window, y, x);
#else
    y = winp->window->_begy;
#endif
    return INT2FIX(y);
}
bkgd(ch) click to toggle source

Set the background of the current window and apply character Integer ch to every character.

see also Curses.bkgd

static VALUE
window_bkgd(VALUE obj, VALUE ch)
{
#ifdef HAVE_WBKGD
    struct windata *winp;

    GetWINDOW(obj,winp);
    return (wbkgd(winp->window, NUM2CH(ch)) == OK) ? Qtrue : Qfalse;
#else
    return Qfalse;
#endif
}
bkgdset(ch) click to toggle source

Manipulate the background of the current window with character Integer ch

see also Curses.bkgdset

static VALUE
window_bkgdset(VALUE obj, VALUE ch)
{
#ifdef HAVE_WBKGDSET
    struct windata *winp;

    GetWINDOW(obj,winp);
    wbkgdset(winp->window, NUM2CH(ch));
#endif
    return Qnil;
}
box(vert, hor) click to toggle source

set the characters to frame the window in. The vertical vert and horizontal hor character.

win = Curses::Window.new(5,5,5,5)
win.box(?|, ?-)
static VALUE
window_box(int argc, VALUE *argv, VALUE self)
{
    struct windata *winp;
    VALUE vert, hor, corn;

    rb_scan_args(argc, argv, "21", &vert, &hor, &corn);

    GetWINDOW(self, winp);
    box(winp->window, NUM2CH(vert), NUM2CH(hor));

    if (!NIL_P(corn)) {
        int cur_x, cur_y, x, y;
        chtype c;

        c = NUM2CH(corn);
        getyx(winp->window, cur_y, cur_x);
        x = NUM2INT(window_maxx(self)) - 1;
        y = NUM2INT(window_maxy(self)) - 1;
        wmove(winp->window, 0, 0);
        waddch(winp->window, c);
        wmove(winp->window, y, 0);
        waddch(winp->window, c);
        wmove(winp->window, y, x);
        waddch(winp->window, c);
        wmove(winp->window, 0, x);
        waddch(winp->window, c);
        wmove(winp->window, cur_y, cur_x);
    }

    return Qnil;
}
clear() click to toggle source

Clear the window.

static VALUE
window_clear(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    wclear(winp->window);

    return Qnil;
}
close() click to toggle source

Deletes the window, and frees the memory

static VALUE
window_close(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    delwin(winp->window);
    winp->window = 0;

    return Qnil;
}
clrtoeol() click to toggle source

Clear the window to the end of line, that the cursor is currently on.

static VALUE
window_clrtoeol(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    wclrtoeol(winp->window);

    return Qnil;
}
color_set(col) click to toggle source

Sets the current color of the given window to the foreground/background combination described by the Fixnum col.

static VALUE
window_color_set(VALUE obj, VALUE col)
{
    struct windata *winp;
    int res;

    GetWINDOW(obj, winp);
    res = wcolor_set(winp->window, NUM2INT(col), NULL);
    return (res == OK) ? Qtrue : Qfalse;
}
curx() click to toggle source

A getter for the current column (X coord) of the window

static VALUE
window_curx(VALUE obj)
{
    struct windata *winp;
    int x, RB_UNUSED_VAR(y);

    GetWINDOW(obj, winp);
    getyx(winp->window, y, x);
    return INT2FIX(x);
}
cury() click to toggle source

A getter for the current line (Y coord) of the window

static VALUE
window_cury(VALUE obj)
{
    struct windata *winp;
    int RB_UNUSED_VAR(x), y;

    GetWINDOW(obj, winp);
    getyx(winp->window, y, x);
    return INT2FIX(y);
}
delch() click to toggle source

Delete the character under the cursor

static VALUE
window_delch(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    wdelch(winp->window);
    return Qnil;
}
deleteln() click to toggle source

Delete the line under the cursor.

static VALUE
window_deleteln(VALUE obj)
{
#if defined(HAVE_WDELETELN) || defined(wdeleteln)
    struct windata *winp;

    GetWINDOW(obj, winp);
    wdeleteln(winp->window);
#endif
    return Qnil;
}
getbkgd() click to toggle source

Returns an Interer (ch) for the character property in the current window.

static VALUE
window_getbkgd(VALUE obj)
{
#ifdef HAVE_WGETBKGD
    chtype c;
    struct windata *winp;

    GetWINDOW(obj,winp);
    return (c = getbkgd(winp->window) != ERR) ? CH2FIX(c) : Qnil;
#else
    return Qnil;
#endif
}
getch() click to toggle source

Read and returns a character from the window.

See Curses::Key to all the function KEY_* available

static VALUE
window_getch(VALUE obj)
{
    struct windata *winp;
    struct wgetch_arg arg;
    int c;

    GetWINDOW(obj, winp);
    arg.win = winp->window;
    rb_thread_call_without_gvl(wgetch_func, (void *)&arg, RUBY_UBF_IO, 0);
    c = arg.c;
    if (c == EOF) return Qnil;
    if (rb_isprint(c)) {
        char ch = (char)c;

        return rb_locale_str_new(&ch, 1);
    }
    return UINT2NUM(c);
}
getstr() click to toggle source

This is equivalent to a series f #getch calls

static VALUE
window_getstr(VALUE obj)
{
    struct windata *winp;
    struct wgetstr_arg arg;

    GetWINDOW(obj, winp);
    arg.win = winp->window;
    rb_thread_call_without_gvl(wgetstr_func, (void *)&arg, RUBY_UBF_IO, 0);
    return rb_locale_str_new_cstr(arg.rtn);
}
idlok(bool) click to toggle source

If bool is true curses considers using the hardware insert/delete line feature of terminals so equipped.

If bool is false, disables use of line insertion and deletion. This option should be enabled only if the application needs insert/delete line, for example, for a screen editor.

It is disabled by default because insert/delete line tends to be visually annoying when used in applications where it is not really needed. If insert/delete line cannot be used, curses redraws the changed portions of all lines.

static VALUE
window_idlok(VALUE obj, VALUE bf)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    idlok(winp->window, RTEST(bf) ? TRUE : FALSE);
    return Qnil;
}
inch() click to toggle source

Returns the character at the current position of the window.

static VALUE
window_inch(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    return CH2FIX(winch(winp->window));
}
insch(ch) click to toggle source

Insert a character ch, before the cursor, in the current window

static VALUE
window_insch(VALUE obj, VALUE ch)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    winsch(winp->window, NUM2CH(ch));

    return Qnil;
}
insertln() click to toggle source

Inserts a line above the cursor, and the bottom line is lost

static VALUE
window_insertln(VALUE obj)
{
#if defined(HAVE_WINSERTLN) || defined(winsertln)
    struct windata *winp;

    GetWINDOW(obj, winp);
    winsertln(winp->window);
#endif
    return Qnil;
}
keypad(bool) click to toggle source

Enables the keypad of the user's terminal.

If enabled (bool is true), the user can press a function key (such as an arrow key) and wgetch returns a single value representing the function key, as in KEY_LEFT. If disabled (bool is false), curses does not treat function keys specially and the program has to interpret the escape sequences itself. If the keypad in the terminal can be turned on (made to transmit) and off (made to work locally), turning on this option causes the terminal keypad to be turned on when #getch is called.

The default value for keypad is false.

static VALUE
window_keypad(VALUE obj, VALUE val)
{
    struct windata *winp;

    GetWINDOW(obj,winp);
    /* keypad() of NetBSD's libcurses returns no value */
#if defined(__NetBSD__) && !defined(NCURSES_VERSION)
    keypad(winp->window,(RTEST(val) ? TRUE : FALSE));
    return Qnil;
#else
    /* may have to raise exception on ERR */
    return (keypad(winp->window,RTEST(val) ? TRUE : FALSE)) == OK ?
        Qtrue : Qfalse;
#endif
}
keypad(bool) click to toggle source

Enables the keypad of the user's terminal.

If enabled (bool is true), the user can press a function key (such as an arrow key) and wgetch returns a single value representing the function key, as in KEY_LEFT. If disabled (bool is false), curses does not treat function keys specially and the program has to interpret the escape sequences itself. If the keypad in the terminal can be turned on (made to transmit) and off (made to work locally), turning on this option causes the terminal keypad to be turned on when #getch is called.

The default value for keypad is false.

static VALUE
window_keypad(VALUE obj, VALUE val)
{
    struct windata *winp;

    GetWINDOW(obj,winp);
    /* keypad() of NetBSD's libcurses returns no value */
#if defined(__NetBSD__) && !defined(NCURSES_VERSION)
    keypad(winp->window,(RTEST(val) ? TRUE : FALSE));
    return Qnil;
#else
    /* may have to raise exception on ERR */
    return (keypad(winp->window,RTEST(val) ? TRUE : FALSE)) == OK ?
        Qtrue : Qfalse;
#endif
}
maxx() click to toggle source

A getter for the maximum columns for the window

static VALUE
window_maxx(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
#if defined(getmaxx)
    return INT2FIX(getmaxx(winp->window));
#elif defined(getmaxyx)
    {
        int x, y;
        getmaxyx(winp->window, y, x);
        return INT2FIX(x);
    }
#else
    return INT2FIX(winp->window->_maxx+1);
#endif
}
maxy() click to toggle source

A getter for the maximum lines for the window

static VALUE
window_maxy(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
#if defined(getmaxy)
    return INT2FIX(getmaxy(winp->window));
#elif defined(getmaxyx)
    {
        int x, y;
        getmaxyx(winp->window, y, x);
        return INT2FIX(y);
    }
#else
    return INT2FIX(winp->window->_maxy+1);
#endif
}
move(y,x) click to toggle source

Moves the window so that the upper left-hand corner is at position (y, x)

static VALUE
window_move(VALUE obj, VALUE y, VALUE x)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    mvwin(winp->window, NUM2INT(y), NUM2INT(x));

    return Qnil;
}
nodelay = bool click to toggle source

When in no-delay mode #getch is a non-blocking call. If no input is ready getch returns ERR.

When in delay mode (bool is false which is the default), #getch blocks until a key is pressed.

static VALUE
window_nodelay(VALUE obj, VALUE val)
{
    struct windata *winp;
    GetWINDOW(obj,winp);

    /* nodelay() of NetBSD's libcurses returns no value */
#if defined(__NetBSD__) && !defined(NCURSES_VERSION)
    nodelay(winp->window, RTEST(val) ? TRUE : FALSE);
    return Qnil;
#else
    return nodelay(winp->window,RTEST(val) ? TRUE : FALSE) == OK ? Qtrue : Qfalse;
#endif
}
noutrefresh() click to toggle source

Refreshes the windows and lines.

#noutrefresh allows multiple updates with more efficiency than #refresh alone.

static VALUE
window_noutrefresh(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
#ifdef HAVE_DOUPDATE
    wnoutrefresh(winp->window);
#else
    wrefresh(winp->window);
#endif

    return Qnil;
}
refresh() click to toggle source

Refreshes the windows and lines.

static VALUE
window_refresh(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    wrefresh(winp->window);

    return Qnil;
}
resize(lines, cols) click to toggle source

Resize the current window to Fixnum lines and Fixnum cols

static VALUE
window_resize(VALUE obj, VALUE lin, VALUE col)
{
#if defined(HAVE_WRESIZE)
    struct windata *winp;

    GetWINDOW(obj,winp);
    return wresize(winp->window, NUM2INT(lin), NUM2INT(col)) == OK ? Qtrue : Qfalse;
#else
    return Qnil;
#endif
}
scrl(num) click to toggle source

Scrolls the current window Fixnum num lines. The current cursor position is not changed.

For positive num, it scrolls up.

For negative num, it scrolls down.

static VALUE
window_scrl(VALUE obj, VALUE n)
{
#ifdef HAVE_WSCRL
    struct windata *winp;

    GetWINDOW(obj, winp);
    /* may have to raise exception on ERR */
    return (wscrl(winp->window,NUM2INT(n)) == OK) ? Qtrue : Qfalse;
#else
    return Qfalse;
#endif
}
scroll() click to toggle source

Scrolls the current window up one line.

static VALUE
window_scroll(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    /* may have to raise exception on ERR */
    return (scroll(winp->window) == OK) ? Qtrue : Qfalse;
}
scrollok(bool) click to toggle source

Controls what happens when the cursor of a window is moved off the edge of the window or scrolling region, either as a result of a newline action on the bottom line, or typing the last character of the last line.

If disabled, (bool is false), the cursor is left on the bottom line.

If enabled, (bool is true), the window is scrolled up one line (Note that to get the physical scrolling effect on the terminal, it is also necessary to call #idlok)

static VALUE
window_scrollok(VALUE obj, VALUE bf)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    scrollok(winp->window, RTEST(bf) ? TRUE : FALSE);
    return Qnil;
}
setpos(y, x) click to toggle source

A setter for the position of the cursor in the current window, using coordinates x and y

static VALUE
window_setpos(VALUE obj, VALUE y, VALUE x)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    wmove(winp->window, NUM2INT(y), NUM2INT(x));
    return Qnil;
}
setscrreg(top, bottom) click to toggle source

Set a software scrolling region in a window. top and bottom are lines numbers of the margin.

If this option and #scrollok are enabled, an attempt to move off the bottom margin line causes all lines in the scrolling region to scroll one line in the direction of the first line. Only the text of the window is scrolled.

static VALUE
window_setscrreg(VALUE obj, VALUE top, VALUE bottom)
{
#ifdef HAVE_WSETSCRREG
    struct windata *winp;
    int res;

    GetWINDOW(obj, winp);
    res = wsetscrreg(winp->window, NUM2INT(top), NUM2INT(bottom));
    /* may have to raise exception on ERR */
    return (res == OK) ? Qtrue : Qfalse;
#else
    return Qfalse;
#endif
}
standend() click to toggle source

Enables the Normal display (no highlight)

This is equivalent to #attron

see also #attrset

static VALUE
window_standend(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    wstandend(winp->window);
    return Qnil;
}
standout() click to toggle source

Enables the best highlighting mode of the terminal.

This is equivalent to #attron

see also #attrset

static VALUE
window_standout(VALUE obj)
{
    struct windata *winp;

    GetWINDOW(obj, winp);
    wstandout(winp->window);
    return Qnil;
}
subwin(height, width, top, left) click to toggle source

Contruct a new subwindow with constraints of height lines, width columns, begin at top line, and begin left most column.

static VALUE
window_subwin(VALUE obj, VALUE height, VALUE width, VALUE top, VALUE left)
{
    struct windata *winp;
    WINDOW *window;
    VALUE win;
    int h, w, t, l;

    h = NUM2INT(height);
    w = NUM2INT(width);
    t = NUM2INT(top);
    l = NUM2INT(left);
    GetWINDOW(obj, winp);
    window = subwin(winp->window, h, w, t, l);
    win = prep_window(rb_obj_class(obj), window);

    return win;
}
timeout=(delay) click to toggle source

Sets block and non-blocking reads for the window.

  • If delay is negative, blocking read is used (i.e., waits indefinitely for input).

  • If delay is zero, then non-blocking read is used (i.e., read returns ERR if no input is waiting).

  • If delay is positive, then read blocks for delay milliseconds, and returns ERR if there is still no input.

static VALUE
window_timeout(VALUE obj, VALUE delay)
{
    struct windata *winp;
    GetWINDOW(obj,winp);

    wtimeout(winp->window,NUM2INT(delay));
    return Qnil;
}


class DBM - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DBM

Documented by mathew meta@pobox.com.

Introduction

The DBM class provides a wrapper to a Unix-style dbm or Database Manager library.

Dbm databases do not have tables or columns; they are simple key-value data stores, like a Ruby Hash except not resident in RAM. Keys and values must be strings.

The exact library used depends on how Ruby was compiled. It could be any of the following:

  • The original ndbm library is released in 4.3BSD. It is based on dbm library in Unix Version 7 but has different API to support multiple databases in a process.

  • Berkeley DB versions 1 thru 5, also known as BDB and Sleepycat DB, now owned by Oracle Corporation.

  • Berkeley DB 1.x, still found in 4.4BSD derivatives (FreeBSD, OpenBSD, etc).

  • gdbm, the GNU implementation of dbm.

  • qdbm, another open source reimplementation of dbm.

All of these dbm implementations have their own Ruby interfaces available, which provide richer (but varying) APIs.

Cautions

Before you decide to use DBM, there are some issues you should consider:

  • Each implementation of dbm has its own file format. Generally, dbm libraries will not read each other's files. This makes dbm files a bad choice for data exchange.

  • Even running the same OS and the same dbm implementation, the database file format may depend on the CPU architecture. For example, files may not be portable between PowerPC and 386, or between 32 and 64 bit Linux.

  • Different versions of Berkeley DB use different file formats. A change to the OS may therefore break DBM access to existing files.

  • Data size limits vary between implementations. Original Berkeley DB was limited to 2GB of data. Dbm libraries also sometimes limit the total size of a key/value pair, and the total size of all the keys that hash to the same value. These limits can be as little as 512 bytes. That said, gdbm and recent versions of Berkeley DB do away with these limits.

Given the above cautions, DBM is not a good choice for long term storage of important data. It is probably best used as a fast and easy alternative to a Hash for processing large amounts of data.

Example

require 'dbm'
db = DBM.open('rfcs', 666, DBM::CREATRW)
db['822'] = 'Standard for the Format of ARPA Internet Text Messages'
db['1123'] = 'Requirements for Internet Hosts - Application and Support'
db['3068'] = 'An Anycast Prefix for 6to4 Relay Routers'
puts db['822']

In Files

  • ext/dbm/dbm.c

Parent

Object

Included Modules

  • Enumerable

Constants

NEWDB

Indicates that dbm_open() should open the database in read/write mode, create it if it does not already exist, and delete all contents if it does already exist.

READER

Indicates that dbm_open() should open the database in read-only mode

VERSION

45)“

  • “QDBM 1.8.78”

WRCREAT

Indicates that dbm_open() should open the database in read/write mode, and create it if it does not already exist

WRITER

Indicates that dbm_open() should open the database in read/write mode

Public Class Methods

new(filename[, mode[, flags]]) → dbm click to toggle source

Open a dbm database with the specified name, which can include a directory path. Any file extensions needed will be supplied automatically by the dbm library. For example, Berkeley DB appends '.db', and GNU gdbm uses two physical files with extensions '.dir' and '.pag'.

The mode should be an integer, as for Unix chmod.

Flags should be one of READER, WRITER, WRCREAT or NEWDB.

static VALUE
fdbm_initialize(int argc, VALUE *argv, VALUE obj)
{
    volatile VALUE file;
    VALUE vmode, vflags;
    DBM *dbm;
    struct dbmdata *dbmp;
    int mode, flags = 0;

    if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
        mode = 0666;           /* default value */
    }
    else if (NIL_P(vmode)) {
        mode = -1;             /* return nil if DB not exist */
    }
    else {
        mode = NUM2INT(vmode);
    }

    if (!NIL_P(vflags))
        flags = NUM2INT(vflags);

    FilePathValue(file);

    /*
     * Note:
     * gdbm 1.10 works with O_CLOEXEC.  gdbm 1.9.1 silently ignore it.
     */
#ifndef O_CLOEXEC
#   define O_CLOEXEC 0
#endif

    if (flags & RUBY_DBM_RW_BIT) {
        flags &= ~RUBY_DBM_RW_BIT;
        dbm = dbm_open(RSTRING_PTR(file), flags|O_CLOEXEC, mode);
    }
    else {
        dbm = 0;
        if (mode >= 0) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT|O_CLOEXEC, mode);
        }
        if (!dbm) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDWR|O_CLOEXEC, 0);
        }
        if (!dbm) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDONLY|O_CLOEXEC, 0);
        }
    }

    if (dbm) {
    /*
     * History of dbm_pagfno() and dbm_dirfno() in ndbm and its compatibles.
     * (dbm_pagfno() and dbm_dirfno() is not standardized.)
     *
     * 1986: 4.3BSD provides ndbm.
     *       It provides dbm_pagfno() and dbm_dirfno() as macros.
     * 1991: gdbm-1.5 provides them as functions.
     *       They returns a same descriptor.
     *       (Earlier releases may have the functions too.)
     * 1991: Net/2 provides Berkeley DB.
     *       It doesn't provide dbm_pagfno() and dbm_dirfno().
     * 1992: 4.4BSD Alpha provides Berkeley DB with dbm_dirfno() as a function.
     *       dbm_pagfno() is a macro as DBM_PAGFNO_NOT_AVAILABLE.
     * 1997: Berkeley DB 2.0 is released by Sleepycat Software, Inc.
     *       It defines dbm_pagfno() and dbm_dirfno() as macros.
     * 2011: gdbm-1.9 creates a separate dir file.
     *       dbm_pagfno() and dbm_dirfno() returns different descriptors.
     */
#if defined(HAVE_DBM_PAGFNO)
        rb_fd_fix_cloexec(dbm_pagfno(dbm));
#endif
#if defined(HAVE_DBM_DIRFNO)
        rb_fd_fix_cloexec(dbm_dirfno(dbm));
#endif

#if defined(RUBYDBM_DB_HEADER) && defined(HAVE_TYPE_DBC)
    /* Disable Berkeley DB error messages such as:
     * DB->put: attempt to modify a read-only database */
        ((DBC*)dbm)->dbp->set_errfile(((DBC*)dbm)->dbp, NULL);
#endif
    }

    if (!dbm) {
        if (mode == -1) return Qnil;
        rb_sys_fail_str(file);
    }

    dbmp = ALLOC(struct dbmdata);
    DATA_PTR(obj) = dbmp;
    dbmp->di_dbm = dbm;
    dbmp->di_size = -1;

    return obj;
}
open(filename[, mode[, flags]]) → dbm click to toggle source
open(filename[, mode[, flags]]) {|dbm| block}

Open a dbm database and yields it if a block is given. See also DBM.new.

static VALUE
fdbm_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);

    if (NIL_P(fdbm_initialize(argc, argv, obj))) {
        return Qnil;
    }

    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, obj, fdbm_close, obj);
    }

    return obj;
}

Public Instance Methods

dbm[key] → string value or nil click to toggle source

Return a value from the database by locating the key string provided. If the key is not found, returns nil.

static VALUE
fdbm_aref(VALUE obj, VALUE keystr)
{
    return fdbm_fetch(obj, keystr, Qnil);
}
store(key, value) → value click to toggle source
dbm[key] = value

Stores the specified string value in the database, indexed via the string key provided.

static VALUE
fdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    fdbm_modify(obj);
    keystr = rb_obj_as_string(keystr);
    valstr = rb_obj_as_string(valstr);

    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_DSIZE(keystr);

    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_DSIZE(valstr);

    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;
    if (dbm_store(dbm, key, val, DBM_REPLACE)) {
        dbm_clearerr(dbm);
        if (errno == EPERM) rb_sys_fail(0);
        rb_raise(rb_eDBMError, "dbm_store failed");
    }

    return valstr;
}
clear click to toggle source

Deletes all data from the database.

static VALUE
fdbm_clear(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;
    while (key = dbm_firstkey(dbm), key.dptr) {
        if (dbm_delete(dbm, key)) {
            rb_raise(rb_eDBMError, "dbm_delete failed");
        }
    }
    dbmp->di_size = 0;

    return obj;
}
close click to toggle source

Closes the database.

static VALUE
fdbm_close(VALUE obj)
{
    struct dbmdata *dbmp;

    GetDBM(obj, dbmp);
    dbm_close(dbmp->di_dbm);
    dbmp->di_dbm = 0;

    return Qnil;
}
closed? → true or false click to toggle source

Returns true if the database is closed, false otherwise.

static VALUE
fdbm_closed(VALUE obj)
{
    struct dbmdata *dbmp;

    Data_Get_Struct(obj, struct dbmdata, dbmp);
    if (dbmp == 0)
        return Qtrue;
    if (dbmp->di_dbm == 0)
        return Qtrue;

    return Qfalse;
}
delete(key) click to toggle source

Deletes an entry from the database.

static VALUE
fdbm_delete(VALUE obj, VALUE keystr)
{
    datum key, value;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE valstr;
    long len;

    fdbm_modify(obj);
    ExportStringValue(keystr);
    len = RSTRING_LEN(keystr);
    if (TOO_LONG(len)) goto not_found;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (DSIZE_TYPE)len;

    GetDBM2(obj, dbmp, dbm);

    value = dbm_fetch(dbm, key);
    if (value.dptr == 0) {
      not_found:
        if (rb_block_given_p()) return rb_yield(keystr);
        return Qnil;
    }

    /* need to save value before dbm_delete() */
    valstr = rb_tainted_str_new(value.dptr, value.dsize);

    if (dbm_delete(dbm, key)) {
        dbmp->di_size = -1;
        rb_raise(rb_eDBMError, "dbm_delete failed");
    }
    else if (dbmp->di_size >= 0) {
        dbmp->di_size--;
    }
    return valstr;
}
reject! {|key, value| block} → self click to toggle source
delete_if {|key, value| block} → self

Deletes all entries for which the code block returns true. Returns self.

static VALUE
fdbm_delete_if(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_tmp_new(0);
    int i, status = 0;
    long n;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    n = dbmp->di_size;
    dbmp->di_size = -1;

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        keystr = rb_tainted_str_new(key.dptr, key.dsize);
        OBJ_FREEZE(keystr);
        valstr = rb_tainted_str_new(val.dptr, val.dsize);
        ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
        if (status != 0) break;
        if (RTEST(ret)) rb_ary_push(ary, keystr);
        GetDBM2(obj, dbmp, dbm);
    }

    for (i = 0; i < RARRAY_LEN(ary); i++) {
        keystr = RARRAY_PTR(ary)[i];
        key.dptr = RSTRING_PTR(keystr);
        key.dsize = (DSIZE_TYPE)RSTRING_LEN(keystr);
        if (dbm_delete(dbm, key)) {
            rb_raise(rb_eDBMError, "dbm_delete failed");
        }
    }
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - RARRAY_LEN(ary);
    rb_ary_clear(ary);

    return obj;
}
each_pair {|key,value| block} → self click to toggle source

Calls the block once for each [key, value] pair in the database. Returns self.

static VALUE
fdbm_each_pair(VALUE obj)
{
    datum key, val;
    DBM *dbm;
    struct dbmdata *dbmp;
    VALUE keystr, valstr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        keystr = rb_tainted_str_new(key.dptr, key.dsize);
        valstr = rb_tainted_str_new(val.dptr, val.dsize);
        rb_yield(rb_assoc_new(keystr, valstr));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}
each_key {|key| block} → self click to toggle source

Calls the block once for each key string in the database. Returns self.

static VALUE
fdbm_each_key(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}
each_pair {|key,value| block} → self click to toggle source

Calls the block once for each [key, value] pair in the database. Returns self.

static VALUE
fdbm_each_pair(VALUE obj)
{
    datum key, val;
    DBM *dbm;
    struct dbmdata *dbmp;
    VALUE keystr, valstr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        keystr = rb_tainted_str_new(key.dptr, key.dsize);
        valstr = rb_tainted_str_new(val.dptr, val.dsize);
        rb_yield(rb_assoc_new(keystr, valstr));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}
each_value {|value| block} → self click to toggle source

Calls the block once for each value string in the database. Returns self.

static VALUE
fdbm_each_value(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        rb_yield(rb_tainted_str_new(val.dptr, val.dsize));
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}
empty? click to toggle source

Returns true if the database is empty, false otherwise.

static VALUE
fdbm_empty_p(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;

    GetDBM2(obj, dbmp, dbm);
    if (dbmp->di_size < 0) {
        dbm = dbmp->di_dbm;

        for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
            return Qfalse;
        }
    }
    else {
        if (dbmp->di_size)
            return Qfalse;
    }
    return Qtrue;
}
fetch(key[, ifnone]) → value click to toggle source

Return a value from the database by locating the key string provided. If the key is not found, returns ifnone. If ifnone is not given, raises IndexError.

static VALUE
fdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
{
    VALUE keystr, valstr, ifnone;

    rb_scan_args(argc, argv, "11", &keystr, &ifnone);
    valstr = fdbm_fetch(obj, keystr, ifnone);
    if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
        rb_raise(rb_eIndexError, "key not found");

    return valstr;
}
has_key?(key) → boolean click to toggle source

Returns true if the database contains the specified key, false otherwise.

static VALUE
fdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    long len;

    ExportStringValue(keystr);
    len = RSTRING_LEN(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (DSIZE_TYPE)len;

    GetDBM2(obj, dbmp, dbm);
    val = dbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
has_value?(value) → boolean click to toggle source

Returns true if the database contains the specified string value, false otherwise.

static VALUE
fdbm_has_value(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    long len;

    ExportStringValue(valstr);
    len = RSTRING_LEN(valstr);
    if (TOO_LONG(len)) return Qfalse;
    val.dptr = RSTRING_PTR(valstr);
    val.dsize = (DSIZE_TYPE)len;

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        if ((DSIZE_TYPE)val.dsize == (DSIZE_TYPE)RSTRING_LEN(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
            return Qtrue;
    }
    return Qfalse;
}
has_key?(key) → boolean click to toggle source

Returns true if the database contains the specified key, false otherwise.

static VALUE
fdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    long len;

    ExportStringValue(keystr);
    len = RSTRING_LEN(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (DSIZE_TYPE)len;

    GetDBM2(obj, dbmp, dbm);
    val = dbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
invert → hash click to toggle source

Returns a Hash (not a DBM database) created by using each value in the database as a key, with the corresponding key as its value.

static VALUE
fdbm_invert(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;
    VALUE hash = rb_hash_new();

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        keystr = rb_tainted_str_new(key.dptr, key.dsize);
        valstr = rb_tainted_str_new(val.dptr, val.dsize);
        rb_hash_aset(hash, valstr, keystr);
    }
    return hash;
}
key(value) → string click to toggle source

Returns the key for the specified value.

static VALUE
fdbm_key(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    long len;

    ExportStringValue(valstr);
    len = RSTRING_LEN(valstr);
    if (TOO_LONG(len)) return Qnil;
    val.dptr = RSTRING_PTR(valstr);
    val.dsize = (DSIZE_TYPE)len;

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        if ((long)val.dsize == RSTRING_LEN(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0) {
            return rb_tainted_str_new(key.dptr, key.dsize);
        }
    }
    return Qnil;
}
has_key?(key) → boolean click to toggle source

Returns true if the database contains the specified key, false otherwise.

static VALUE
fdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    long len;

    ExportStringValue(keystr);
    len = RSTRING_LEN(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (DSIZE_TYPE)len;

    GetDBM2(obj, dbmp, dbm);
    val = dbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
keys → array click to toggle source

Returns an array of all the string keys in the database.

static VALUE
fdbm_keys(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);

    ary = rb_ary_new();
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        rb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize));
    }

    return ary;
}
length → integer click to toggle source

Returns the number of entries in the database.

static VALUE
fdbm_length(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;
    int i = 0;

    GetDBM2(obj, dbmp, dbm);
    if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}
has_key?(key) → boolean click to toggle source

Returns true if the database contains the specified key, false otherwise.

static VALUE
fdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    long len;

    ExportStringValue(keystr);
    len = RSTRING_LEN(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (DSIZE_TYPE)len;

    GetDBM2(obj, dbmp, dbm);
    val = dbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
reject {|key,value| block} → Hash click to toggle source

Converts the contents of the database to an in-memory Hash, then calls Hash#reject with the specified code block, returning a new Hash.

static VALUE
fdbm_reject(VALUE obj)
{
    return rb_hash_delete_if(fdbm_to_hash(obj));
}
reject! {|key, value| block} → self click to toggle source
delete_if {|key, value| block} → self

Deletes all entries for which the code block returns true. Returns self.

static VALUE
fdbm_delete_if(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_tmp_new(0);
    int i, status = 0;
    long n;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    n = dbmp->di_size;
    dbmp->di_size = -1;

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        keystr = rb_tainted_str_new(key.dptr, key.dsize);
        OBJ_FREEZE(keystr);
        valstr = rb_tainted_str_new(val.dptr, val.dsize);
        ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
        if (status != 0) break;
        if (RTEST(ret)) rb_ary_push(ary, keystr);
        GetDBM2(obj, dbmp, dbm);
    }

    for (i = 0; i < RARRAY_LEN(ary); i++) {
        keystr = RARRAY_PTR(ary)[i];
        key.dptr = RSTRING_PTR(keystr);
        key.dsize = (DSIZE_TYPE)RSTRING_LEN(keystr);
        if (dbm_delete(dbm, key)) {
            rb_raise(rb_eDBMError, "dbm_delete failed");
        }
    }
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - RARRAY_LEN(ary);
    rb_ary_clear(ary);

    return obj;
}
replace(obj) click to toggle source

Replaces the contents of the database with the contents of the specified object. Takes any object which implements the #each_pair method, including Hash and DBM objects.

static VALUE
fdbm_replace(VALUE obj, VALUE other)
{
    fdbm_clear(obj);
    rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
    return obj;
}
select {|key, value| block} → array click to toggle source

Returns a new array consisting of the [key, value] pairs for which the code block returns true.

static VALUE
fdbm_select(VALUE obj)
{
    VALUE new = rb_ary_new();
    datum key, val;
    DBM *dbm;
    struct dbmdata *dbmp;

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        VALUE assoc, v;
        val = dbm_fetch(dbm, key);
        assoc = rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
                             rb_tainted_str_new(val.dptr, val.dsize));
        v = rb_yield(assoc);
        if (RTEST(v)) {
            rb_ary_push(new, assoc);
        }
        GetDBM2(obj, dbmp, dbm);
    }

    return new;
}
shift() → [key, value] click to toggle source

Removes a [key, value] pair from the database, and returns it. If the database is empty, returns nil. The order in which values are removed/returned is not guaranteed.

static VALUE
fdbm_shift(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;

    key = dbm_firstkey(dbm);
    if (!key.dptr) return Qnil;
    val = dbm_fetch(dbm, key);
    keystr = rb_tainted_str_new(key.dptr, key.dsize);
    valstr = rb_tainted_str_new(val.dptr, val.dsize);
    dbm_delete(dbm, key);

    return rb_assoc_new(keystr, valstr);
}
length → integer click to toggle source

Returns the number of entries in the database.

static VALUE
fdbm_length(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;
    int i = 0;

    GetDBM2(obj, dbmp, dbm);
    if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}
store(key, value) → value click to toggle source
dbm[key] = value

Stores the specified string value in the database, indexed via the string key provided.

static VALUE
fdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    fdbm_modify(obj);
    keystr = rb_obj_as_string(keystr);
    valstr = rb_obj_as_string(valstr);

    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_DSIZE(keystr);

    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_DSIZE(valstr);

    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;
    if (dbm_store(dbm, key, val, DBM_REPLACE)) {
        dbm_clearerr(dbm);
        if (errno == EPERM) rb_sys_fail(0);
        rb_raise(rb_eDBMError, "dbm_store failed");
    }

    return valstr;
}
to_a → array click to toggle source

Converts the contents of the database to an array of [key, value] arrays, and returns it.

static VALUE
fdbm_to_a(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        rb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
                                      rb_tainted_str_new(val.dptr, val.dsize)));
    }

    return ary;
}
to_hash → hash click to toggle source

Converts the contents of the database to an in-memory Hash object, and returns it.

static VALUE
fdbm_to_hash(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE hash;

    GetDBM2(obj, dbmp, dbm);
    hash = rb_hash_new();
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        rb_hash_aset(hash, rb_tainted_str_new(key.dptr, key.dsize),
                           rb_tainted_str_new(val.dptr, val.dsize));
    }

    return hash;
}
update(obj) click to toggle source

Updates the database with multiple values from the specified object. Takes any object which implements the #each_pair method, including Hash and DBM objects.

static VALUE
fdbm_update(VALUE obj, VALUE other)
{
    rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
    return obj;
}
has_value?(value) → boolean click to toggle source

Returns true if the database contains the specified string value, false otherwise.

static VALUE
fdbm_has_value(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    long len;

    ExportStringValue(valstr);
    len = RSTRING_LEN(valstr);
    if (TOO_LONG(len)) return Qfalse;
    val.dptr = RSTRING_PTR(valstr);
    val.dsize = (DSIZE_TYPE)len;

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        if ((DSIZE_TYPE)val.dsize == (DSIZE_TYPE)RSTRING_LEN(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
            return Qtrue;
    }
    return Qfalse;
}
values → array click to toggle source

Returns an array of all the string values in the database.

static VALUE
fdbm_values(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        rb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize));
    }

    return ary;
}
values_at(key, ...) → Array click to toggle source

Returns an array containing the values associated with the given keys.

static VALUE
fdbm_values_at(int argc, VALUE *argv, VALUE obj)
{
    VALUE new = rb_ary_new2(argc);
    int i;

    for (i=0; i<argc; i++) {
        rb_ary_push(new, fdbm_fetch(obj, argv[i], Qnil));
    }

    return new;
}


class DBMError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DBMError

Exception class used to return errors from the dbm library.

In Files

  • ext/dbm/dbm.c

Parent

StandardError


class DEBUGGER__ - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DEBUGGER__

This library provides debugging functionality to Ruby.

To add a debugger to your code, start by requiring debug in your program:

def say(word)
  require 'debug'
  puts word
end

This will cause Ruby to interrupt execution and show a prompt when the say method is run.

Once you're inside the prompt, you can start debugging your program.

(rdb:1) p word
"hello"

Getting help

You can get help at any time by pressing h.

(rdb:1) h
Debugger help v.-0.002b
Commands
  b[reak] [file:|class:]<line|method>
  b[reak] [class.]<line|method>
                             set breakpoint to some position
  wat[ch] <expression>       set watchpoint to some expression
  cat[ch] (<exception>|off)  set catchpoint to an exception
  b[reak]                    list breakpoints
  cat[ch]                    show catchpoint
  del[ete][ nnn]             delete some or all breakpoints
  disp[lay] <expression>     add expression into display expression list
  undisp[lay][ nnn]          delete one particular or all display expressions
  c[ont]                     run until program ends or hit breakpoint
  s[tep][ nnn]               step (into methods) one line or till line nnn
  n[ext][ nnn]               go over one line or till line nnn
  w[here]                    display frames
  f[rame]                    alias for where
  l[ist][ (-|nn-mm)]         list program, - lists backwards
                             nn-mm lists given lines
  up[ nn]                    move to higher frame
  down[ nn]                  move to lower frame
  fin[ish]                   return to outer frame
  tr[ace] (on|off)           set trace mode of current thread
  tr[ace] (on|off) all       set trace mode of all threads
  q[uit]                     exit from debugger
  v[ar] g[lobal]             show global variables
  v[ar] l[ocal]              show local variables
  v[ar] i[nstance] <object>  show instance variables of object
  v[ar] c[onst] <object>     show constants of object
  m[ethod] i[nstance] <obj>  show methods of object
  m[ethod] <class|module>    show instance methods of class or module
  th[read] l[ist]            list all threads
  th[read] c[ur[rent]]       show current thread
  th[read] [sw[itch]] <nnn>  switch thread context to nnn
  th[read] stop <nnn>        stop thread nnn
  th[read] resume <nnn>      resume thread nnn
  p expression               evaluate expression and print its value
  h[elp]                     print this help
  <everything else>          evaluate

Usage

The following is a list of common functionalities that the debugger provides.

Navigating through your code

In general, a debugger is used to find bugs in your program, which often means pausing execution and inspecting variables at some point in time.

Let's look at an example:

def my_method(foo)
  require 'debug'
  foo = get_foo if foo.nil?
  raise if foo.nil?
end

When you run this program, the debugger will kick in just before the foo assignment.

(rdb:1) p foo
nil

In this example, it'd be interesting to move to the next line and inspect the value of foo again. You can do that by pressing n:

(rdb:1) n # goes to next line
(rdb:1) p foo
nil

You now know that the original value of foo was nil, and that it still was nil after calling get_foo.

Other useful commands for navigating through your code are:

c

Runs the program until it either exists or encounters another breakpoint. You usually press c when you are finished debugging your program and want to resume its execution.

s

Steps into method definition. In the previous example, s would take you inside the method definition of get_foo.

r

Restart the program.

q

Quit the program.

Inspecting variables

You can use the debugger to easily inspect both local and global variables. We've seen how to inspect local variables before:

(rdb:1) p my_arg
42

You can also pretty print the result of variables or expressions:

(rdb:1) pp %w{a very long long array containing many words}
["a",
 "very",
 "long",
 ...
]

You can list all local variables with +v l+:

(rdb:1) v l
  foo => "hello"

Similarly, you can show all global variables with +v g+:

(rdb:1) v g
  all global variables

Finally, you can omit p if you simply want to evaluate a variable or expression

(rdb:1) 5**2
25

Going beyond basics

Ruby Debug provides more advanced functionalities like switching between threads, setting breakpoints and watch expressions, and more. The full list of commands is available at any time by pressing h.

Staying out of trouble

Make sure you remove every instance of +require 'debug'+ before shipping your code. Failing to do so may result in your program hanging unpredictably.

Debug is not available in safe mode.

In Files

  • lib/debug.rb

Parent

Object

Public Class Methods

break_points() click to toggle source

Returns the list of break points where execution will be stopped.

See DEBUGGER__ for more useage

# File lib/debug.rb, line 914
def break_points
  @break_points
end
context(thread=Thread.current) click to toggle source
# File lib/debug.rb, line 968
def context(thread=Thread.current)
  c = thread[:__debugger_data__]
  unless c
    thread[:__debugger_data__] = c = Context.new
  end
  c
end
debug_thread_info(input, binding) click to toggle source
# File lib/debug.rb, line 1024
def debug_thread_info(input, binding)
  case input
  when /^l(?:ist)?/
    make_thread_list
    thread_list_all

  when /^c(?:ur(?:rent)?)?$/
    make_thread_list
    thread_list(@thread_list[Thread.current])

  when /^(?:sw(?:itch)?\s+)?(\d+)/
    make_thread_list
    th = get_thread($1.to_i)
    if th == Thread.current
      @stdout.print "It's the current thread.\n"
    else
      thread_list(@thread_list[th])
      context(th).stop_next
      th.run
      return :cont
    end

  when /^stop\s+(\d+)/
    make_thread_list
    th = get_thread($1.to_i)
    if th == Thread.current
      @stdout.print "It's the current thread.\n"
    elsif th.stop?
      @stdout.print "Already stopped.\n"
    else
      thread_list(@thread_list[th])
      context(th).suspend
    end

  when /^resume\s+(\d+)/
    make_thread_list
    th = get_thread($1.to_i)
    if th == Thread.current
      @stdout.print "It's the current thread.\n"
    elsif !th.stop?
      @stdout.print "Already running."
    else
      thread_list(@thread_list[th])
      th.run
    end
  end
end
display() click to toggle source

Returns the display expression list

See DEBUGGER__ for more usage

# File lib/debug.rb, line 907
def display
  @display
end
get_thread(num) click to toggle source
# File lib/debug.rb, line 980
def get_thread(num)
  th = @thread_list.key(num)
  unless th
    @stdout.print "No thread ##{num}\n"
    throw :debug_error
  end
  th
end
interrupt() click to toggle source
# File lib/debug.rb, line 976
def interrupt
  context(@last_thread).stop_next
end
make_thread_list() click to toggle source
# File lib/debug.rb, line 1011
def make_thread_list
  hash = {}
  for th in Thread::list
    if @thread_list.key? th
      hash[th] = @thread_list[th]
    else
      @max_thread += 1
      hash[th] = @max_thread
    end
  end
  @thread_list = hash
end
resume() click to toggle source
# File lib/debug.rb, line 952
def resume
  MUTEX.synchronize do
    make_thread_list
    @thread_list.each do |th,|
      next if th == Thread.current
      context(th).clear_suspend
    end
    waiting.each do |th|
      th.run
    end
    waiting.clear
  end
  # Schedule other threads to restart as soon as possible.
  Thread.pass
end
set_last_thread(th) click to toggle source
# File lib/debug.rb, line 936
def set_last_thread(th)
  @last_thread = th
end
set_trace( arg ) click to toggle source
# File lib/debug.rb, line 926
def set_trace( arg )
  MUTEX.synchronize do
    make_thread_list
    for th, in @thread_list
      context(th).set_trace arg
    end
  end
  arg
end
stdout() click to toggle source

Returns the IO used as stdout. Defaults to STDOUT

# File lib/debug.rb, line 895
def stdout
  @stdout
end
stdout=(s) click to toggle source

Sets the IO used as stdout. Defaults to STDOUT

# File lib/debug.rb, line 900
def stdout=(s)
  @stdout = s
end
suspend() click to toggle source
# File lib/debug.rb, line 940
def suspend
  MUTEX.synchronize do
    make_thread_list
    for th, in @thread_list
      next if th == Thread.current
      context(th).set_suspend
    end
  end
  # Schedule other threads to suspend as soon as possible.
  Thread.pass
end
thread_list(num) click to toggle source
# File lib/debug.rb, line 989
def thread_list(num)
  th = get_thread(num)
  if th == Thread.current
    @stdout.print "+"
  else
    @stdout.print " "
  end
  @stdout.printf "%d ", num
  @stdout.print th.inspect, "\t"
  file = context(th).instance_eval{@file}
  if file
    @stdout.print file,":",context(th).instance_eval{@line}
  end
  @stdout.print "\n"
end
thread_list_all() click to toggle source
# File lib/debug.rb, line 1005
def thread_list_all
  for th in @thread_list.values.sort
    thread_list(th)
  end
end
waiting() click to toggle source

Returns the list of waiting threads.

When stepping through the traces of a function, thread gets suspended, to be resumed later.

# File lib/debug.rb, line 922
def waiting
  @waiting
end

Public Instance Methods

break_points() click to toggle source
# File lib/debug.rb, line 266
def break_points
  DEBUGGER__.break_points
end
check_break_points(file, klass, pos, binding, id) click to toggle source
# File lib/debug.rb, line 791
def check_break_points(file, klass, pos, binding, id)
  return false if break_points.empty?
  n = 1
  for b in break_points
    if b[0]           # valid
      if b[1] == 0    # breakpoint
        if (b[2] == file and b[3] == pos) or
            (klass and b[2] == klass and b[3] == pos)
          stdout.printf "Breakpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos
          return true
        end
      elsif b[1] == 1 # watchpoint
        if debug_silent_eval(b[2], binding)
          stdout.printf "Watchpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos
          return true
        end
      end
    end
    n += 1
  end
  return false
end
context(th) click to toggle source
# File lib/debug.rb, line 274
def context(th)
  DEBUGGER__.context(th)
end
debug_command(file, line, id, binding) click to toggle source
# File lib/debug.rb, line 380
def debug_command(file, line, id, binding)
  MUTEX.lock
  unless defined?($debugger_restart) and $debugger_restart
    callcc{|c| $debugger_restart = c}
  end
  set_last_thread(Thread.current)
  frame_pos = 0
  binding_file = file
  binding_line = line
  previous_line = nil
  if ENV['EMACS']
    stdout.printf "\0032\0032%s:%d:\n", binding_file, binding_line
  else
    stdout.printf "%s:%d:%s", binding_file, binding_line,
      line_at(binding_file, binding_line)
  end
  @frames[0] = [binding, file, line, id]
  display_expressions(binding)
  prompt = true
  while prompt and input = readline("(rdb:%d) "%thnum(), true)
    catch(:debug_error) do
      if input == ""
        next unless DEBUG_LAST_CMD[0]
        input = DEBUG_LAST_CMD[0]
        stdout.print input, "\n"
      else
        DEBUG_LAST_CMD[0] = input
      end

      case input
      when /^\s*tr(?:ace)?(?:\s+(on|off))?(?:\s+(all))?$/
        if defined?( $2 )
          if $1 == 'on'
            set_trace_all true
          else
            set_trace_all false
          end
        elsif defined?( $1 )
          if $1 == 'on'
            set_trace true
          else
            set_trace false
          end
        end
        if trace?
          stdout.print "Trace on.\n"
        else
          stdout.print "Trace off.\n"
        end

      when /^\s*b(?:reak)?\s+(?:(.+):)?([^.:]+)$/
        pos = $2
        if $1
          klass = debug_silent_eval($1, binding)
          file = $1
        end
        if pos =~ /^\d+$/
          pname = pos
          pos = pos.to_i
        else
          pname = pos = pos.intern.id2name
        end
        break_points.push [true, 0, klass || file, pos]
        stdout.printf "Set breakpoint %d at %s:%s\n", break_points.size, klass || file, pname

      when /^\s*b(?:reak)?\s+(.+)[#.]([^.:]+)$/
        pos = $2.intern.id2name
        klass = debug_eval($1, binding)
        break_points.push [true, 0, klass, pos]
        stdout.printf "Set breakpoint %d at %s.%s\n", break_points.size, klass, pos

      when /^\s*wat(?:ch)?\s+(.+)$/
        exp = $1
        break_points.push [true, 1, exp]
        stdout.printf "Set watchpoint %d:%s\n", break_points.size, exp

      when /^\s*b(?:reak)?$/
        if break_points.find{|b| b[1] == 0}
          n = 1
          stdout.print "Breakpoints:\n"
          break_points.each do |b|
            if b[0] and b[1] == 0
              stdout.printf "  %d %s:%s\n", n, b[2], b[3]
            end
            n += 1
          end
        end
        if break_points.find{|b| b[1] == 1}
          n = 1
          stdout.print "\n"
          stdout.print "Watchpoints:\n"
          for b in break_points
            if b[0] and b[1] == 1
              stdout.printf "  %d %s\n", n, b[2]
            end
            n += 1
          end
        end
        if break_points.size == 0
          stdout.print "No breakpoints\n"
        else
          stdout.print "\n"
        end

      when /^\s*del(?:ete)?(?:\s+(\d+))?$/
        pos = $1
        unless pos
          input = readline("Clear all breakpoints? (y/n) ", false)
          if input == "y"
            for b in break_points
              b[0] = false
            end
          end
        else
          pos = pos.to_i
          if break_points[pos-1]
            break_points[pos-1][0] = false
          else
            stdout.printf "Breakpoint %d is not defined\n", pos
          end
        end

      when /^\s*disp(?:lay)?\s+(.+)$/
        exp = $1
        display.push [true, exp]
        stdout.printf "%d: ", display.size
        display_expression(exp, binding)

      when /^\s*disp(?:lay)?$/
        display_expressions(binding)

      when /^\s*undisp(?:lay)?(?:\s+(\d+))?$/
        pos = $1
        unless pos
          input = readline("Clear all expressions? (y/n) ", false)
          if input == "y"
            for d in display
              d[0] = false
            end
          end
        else
          pos = pos.to_i
          if display[pos-1]
            display[pos-1][0] = false
          else
            stdout.printf "Display expression %d is not defined\n", pos
          end
        end

      when /^\s*c(?:ont)?$/
        prompt = false

      when /^\s*s(?:tep)?(?:\s+(\d+))?$/
        if $1
          lev = $1.to_i
        else
          lev = 1
        end
        @stop_next = lev
        prompt = false

      when /^\s*n(?:ext)?(?:\s+(\d+))?$/
        if $1
          lev = $1.to_i
        else
          lev = 1
        end
        @stop_next = lev
        @no_step = @frames.size - frame_pos
        prompt = false

      when /^\s*w(?:here)?$/, /^\s*f(?:rame)?$/
        display_frames(frame_pos)

      when /^\s*l(?:ist)?(?:\s+(.+))?$/
        if not $1
          b = previous_line ? previous_line + 10 : binding_line - 5
          e = b + 9
        elsif $1 == '-'
          b = previous_line ? previous_line - 10 : binding_line - 5
          e = b + 9
        else
          b, e = $1.split(/[-,]/)
          if e
            b = b.to_i
            e = e.to_i
          else
            b = b.to_i - 5
            e = b + 9
          end
        end
        previous_line = b
        display_list(b, e, binding_file, binding_line)

      when /^\s*up(?:\s+(\d+))?$/
        previous_line = nil
        if $1
          lev = $1.to_i
        else
          lev = 1
        end
        frame_pos += lev
        if frame_pos >= @frames.size
          frame_pos = @frames.size - 1
          stdout.print "At toplevel\n"
        end
        binding, binding_file, binding_line = @frames[frame_pos]
        stdout.print format_frame(frame_pos)

      when /^\s*down(?:\s+(\d+))?$/
        previous_line = nil
        if $1
          lev = $1.to_i
        else
          lev = 1
        end
        frame_pos -= lev
        if frame_pos < 0
          frame_pos = 0
          stdout.print "At stack bottom\n"
        end
        binding, binding_file, binding_line = @frames[frame_pos]
        stdout.print format_frame(frame_pos)

      when /^\s*fin(?:ish)?$/
        if frame_pos == @frames.size
          stdout.print "\"finish\" not meaningful in the outermost frame.\n"
        else
          @finish_pos = @frames.size - frame_pos
          frame_pos = 0
          prompt = false
        end

      when /^\s*cat(?:ch)?(?:\s+(.+))?$/
        if $1
          excn = $1
          if excn == 'off'
            @catch = nil
            stdout.print "Clear catchpoint.\n"
          else
            @catch = excn
            stdout.printf "Set catchpoint %s.\n", @catch
          end
        else
          if @catch
            stdout.printf "Catchpoint %s.\n", @catch
          else
            stdout.print "No catchpoint.\n"
          end
        end

      when /^\s*q(?:uit)?$/
        input = readline("Really quit? (y/n) ", false)
        if input == "y"
          exit!  # exit -> exit!: No graceful way to stop threads...
        end

      when /^\s*v(?:ar)?\s+/
        debug_variable_info($', binding)

      when /^\s*m(?:ethod)?\s+/
        debug_method_info($', binding)

      when /^\s*th(?:read)?\s+/
        if DEBUGGER__.debug_thread_info($', binding) == :cont
          prompt = false
        end

      when /^\s*pp\s+/
        PP.pp(debug_eval($', binding), stdout)

      when /^\s*p\s+/
        stdout.printf "%s\n", debug_eval($', binding).inspect

      when /^\s*r(?:estart)?$/
        $debugger_restart.call

      when /^\s*h(?:elp)?$/
        debug_print_help()

      else
        v = debug_eval(input, binding)
        stdout.printf "%s\n", v.inspect
      end
    end
  end
  MUTEX.unlock
  resume_all
end
debug_eval(str, binding) click to toggle source
# File lib/debug.rb, line 286
def debug_eval(str, binding)
  begin
    eval(str, binding)
  rescue StandardError, ScriptError => e
    at = eval("caller(1)", binding)
    stdout.printf "%s:%s\n", at.shift, e.to_s.sub(/\(eval\):1:(in `.*?':)?/, '')
    for i in at
      stdout.printf "\tfrom %s\n", i
    end
    throw :debug_error
  end
end
debug_funcname(id) click to toggle source
# File lib/debug.rb, line 783
def debug_funcname(id)
  if id.nil?
    "toplevel"
  else
    id.id2name
  end
end
debug_method_info(input, binding) click to toggle source
# File lib/debug.rb, line 336
def debug_method_info(input, binding)
  case input
  when /^i(:?nstance)?\s+/
    obj = debug_eval($', binding)

    len = 0
    for v in obj.methods.sort
      len += v.size + 1
      if len > 70
        len = v.size + 1
        stdout.print "\n"
      end
      stdout.print v, " "
    end
    stdout.print "\n"

  else
    obj = debug_eval(input, binding)
    unless obj.kind_of? Module
      stdout.print "Should be Class/Module: ", input, "\n"
    else
      len = 0
      for v in obj.instance_methods(false).sort
        len += v.size + 1
        if len > 70
          len = v.size + 1
          stdout.print "\n"
        end
        stdout.print v, " "
      end
      stdout.print "\n"
    end
  end
end
debug_print_help() click to toggle source
# File lib/debug.rb, line 670
    def debug_print_help
      stdout.print <<EOHELP
Debugger help v.-0.002b
Commands
  b[reak] [file:|class:]<line|method>
  b[reak] [class.]<line|method>
                             set breakpoint to some position
  wat[ch] <expression>       set watchpoint to some expression
  cat[ch] (<exception>|off)  set catchpoint to an exception
  b[reak]                    list breakpoints
  cat[ch]                    show catchpoint
  del[ete][ nnn]             delete some or all breakpoints
  disp[lay] <expression>     add expression into display expression list
  undisp[lay][ nnn]          delete one particular or all display expressions
  c[ont]                     run until program ends or hit breakpoint
  s[tep][ nnn]               step (into methods) one line or till line nnn
  n[ext][ nnn]               go over one line or till line nnn
  w[here]                    display frames
  f[rame]                    alias for where
  l[ist][ (-|nn-mm)]         list program, - lists backwards
                             nn-mm lists given lines
  up[ nn]                    move to higher frame
  down[ nn]                  move to lower frame
  fin[ish]                   return to outer frame
  tr[ace] (on|off)           set trace mode of current thread
  tr[ace] (on|off) all       set trace mode of all threads
  q[uit]                     exit from debugger
  v[ar] g[lobal]             show global variables
  v[ar] l[ocal]              show local variables
  v[ar] i[nstance] <object>  show instance variables of object
  v[ar] c[onst] <object>     show constants of object
  m[ethod] i[nstance] <obj>  show methods of object
  m[ethod] <class|module>    show instance methods of class or module
  th[read] l[ist]            list all threads
  th[read] c[ur[rent]]       show current thread
  th[read] [sw[itch]] <nnn>  switch thread context to nnn
  th[read] stop <nnn>        stop thread nnn
  th[read] resume <nnn>      resume thread nnn
  pp expression              evaluate expression and pretty_print its value
  p expression               evaluate expression and print its value
  r[estart]                  restart program
  h[elp]                     print this help
  <everything else>          evaluate
EOHELP
    end
debug_silent_eval(str, binding) click to toggle source
# File lib/debug.rb, line 299
def debug_silent_eval(str, binding)
  begin
    eval(str, binding)
  rescue StandardError, ScriptError
    nil
  end
end
debug_variable_info(input, binding) click to toggle source
# File lib/debug.rb, line 314
def debug_variable_info(input, binding)
  case input
  when /^\s*g(?:lobal)?\s*$/
    var_list(global_variables, binding)

  when /^\s*l(?:ocal)?\s*$/
    var_list(eval("local_variables", binding), binding)

  when /^\s*i(?:nstance)?\s+/
    obj = debug_eval($', binding)
    var_list(obj.instance_variables, obj.instance_eval{binding()})

  when /^\s*c(?:onst(?:ant)?)?\s+/
    obj = debug_eval($', binding)
    unless obj.kind_of? Module
      stdout.print "Should be Class/Module: ", $', "\n"
    else
      var_list(obj.constants, obj.module_eval{binding()})
    end
  end
end
display() click to toggle source
# File lib/debug.rb, line 270
def display
  DEBUGGER__.display
end
display_expression(exp, binding) click to toggle source
# File lib/debug.rb, line 727
def display_expression(exp, binding)
  stdout.printf "%s = %s\n", exp, debug_silent_eval(exp, binding).to_s
end
display_expressions(binding) click to toggle source
# File lib/debug.rb, line 716
def display_expressions(binding)
  n = 1
  for d in display
    if d[0]
      stdout.printf "%d: ", n
      display_expression(d[1], binding)
    end
    n += 1
  end
end
display_frames(pos) click to toggle source
# File lib/debug.rb, line 738
def display_frames(pos)
  0.upto(@frames.size - 1) do |n|
    if n == pos
      stdout.print "--> "
    else
      stdout.print "    "
    end
    stdout.print format_frame(n)
  end
end
display_list(b, e, file, line) click to toggle source
# File lib/debug.rb, line 755
def display_list(b, e, file, line)
  stdout.printf "[%d, %d] in %s\n", b, e, file
  if lines = SCRIPT_LINES__[file] and lines != true
    b.upto(e) do |n|
      if n > 0 && lines[n-1]
        if n == line
          stdout.printf "=> %d  %s\n", n, lines[n-1].chomp
        else
          stdout.printf "   %d  %s\n", n, lines[n-1].chomp
        end
      end
    end
  else
    stdout.printf "No sourcefile available for %s\n", file
  end
end
excn_handle(file, line, id, binding) click to toggle source
# File lib/debug.rb, line 814
def excn_handle(file, line, id, binding)
  if $!.class <= SystemExit
    set_trace_func nil
    exit
  end

  if @catch and ($!.class.ancestors.find { |e| e.to_s == @catch })
    stdout.printf "%s:%d: `%s' (%s)\n", file, line, $!, $!.class
    fs = @frames.size
    tb = caller(0)[-fs..-1]
    if tb
      for i in tb
        stdout.printf "\tfrom %s\n", i
      end
    end
    suspend_all
    debug_command(file, line, id, binding)
  end
end
format_frame(pos) click to toggle source
# File lib/debug.rb, line 749
def format_frame(pos)
  _, file, line, id = @frames[pos]
  sprintf "#%d %s:%s%s\n", pos + 1, file, line,
    (id ? ":in `#{id.id2name}'" : "")
end
frame_set_pos(file, line) click to toggle source
# File lib/debug.rb, line 731
def frame_set_pos(file, line)
  if @frames[0]
    @frames[0][1] = file
    @frames[0][2] = line
  end
end
line_at(file, line) click to toggle source
# File lib/debug.rb, line 772
def line_at(file, line)
  lines = SCRIPT_LINES__[file]
  if lines
    return "\n" if lines == true
    line = lines[line-1]
    return "\n" unless line
    return line
  end
  return "\n"
end
set_last_thread(th) click to toggle source
# File lib/debug.rb, line 282
def set_last_thread(th)
  DEBUGGER__.set_last_thread(th)
end
set_trace(arg) click to toggle source
# File lib/debug.rb, line 258
def set_trace(arg)
  @trace = arg
end
set_trace_all(arg) click to toggle source
# File lib/debug.rb, line 278
def set_trace_all(arg)
  DEBUGGER__.set_trace(arg)
end
stdout() click to toggle source
# File lib/debug.rb, line 262
def stdout
  DEBUGGER__.stdout
end
thnum() click to toggle source
# File lib/debug.rb, line 371
def thnum
  num = DEBUGGER__.instance_eval{@thread_list[Thread.current]}
  unless num
    DEBUGGER__.make_thread_list
    num = DEBUGGER__.instance_eval{@thread_list[Thread.current]}
  end
  num
end
trace?() click to toggle source
# File lib/debug.rb, line 254
def trace?
  @trace
end
trace_func(event, file, line, id, binding, klass) click to toggle source
# File lib/debug.rb, line 834
def trace_func(event, file, line, id, binding, klass)
  Tracer.trace_func(event, file, line, id, binding, klass) if trace?
  context(Thread.current).check_suspend
  @file = file
  @line = line
  case event
  when 'line'
    frame_set_pos(file, line)
    if !@no_step or @frames.size == @no_step
      @stop_next -= 1
      @stop_next = -1 if @stop_next < 0
    elsif @frames.size < @no_step
      @stop_next = 0          # break here before leaving...
    else
      # nothing to do. skipped.
    end
    if @stop_next == 0 or check_break_points(file, nil, line, binding, id)
      @no_step = nil
      suspend_all
      debug_command(file, line, id, binding)
    end

  when 'call'
    @frames.unshift [binding, file, line, id]
    if check_break_points(file, klass, id.id2name, binding, id)
      suspend_all
      debug_command(file, line, id, binding)
    end

  when 'c-call'
    frame_set_pos(file, line)

  when 'class'
    @frames.unshift [binding, file, line, id]

  when 'return', 'end'
    if @frames.size == @finish_pos
      @stop_next = 1
      @finish_pos = 0
    end
    @frames.shift

  when 'raise'
    excn_handle(file, line, id, binding)

  end
  @last_file = file
end
var_list(ary, binding) click to toggle source
# File lib/debug.rb, line 307
def var_list(ary, binding)
  ary.sort!
  for v in ary
    stdout.printf "  %s => %s\n", v, eval(v.to_s, binding).inspect
  end
end


module DL - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DL

A bridge to the dlopen() or dynamic library linker function.

Example

bash $> cat > sum.c <<EOF
double sum(double *arry, int len)
{
        double ret = 0;
        int i;
        for(i = 0; i < len; i++){
                ret = ret + arry[i];
        }
        return ret;
}

double split(double num)
{
        double ret = 0;
        ret = num / 2;
        return ret;
}
EOF
bash $> gcc -o libsum.so -shared sum.c
bash $> cat > sum.rb <<EOF
require 'dl'
require 'dl/import'

module LibSum
        extend DL::Importer
        dlload './libsum.so'
        extern 'double sum(double*, int)'
        extern 'double split(double)'
end

a = [2.0, 3.0, 4.0]

sum = LibSum.sum(a.pack("d*"), a.count)
p LibSum.split(sum)
EOF
bash $> ruby sum.rb
4.5

WIN! :-)

In Files

  • ext/dl/cfunc.c
  • ext/dl/cptr.c
  • ext/dl/dl.c
  • ext/dl/lib/dl/callback.rb
  • ext/dl/lib/dl/cparser.rb
  • ext/dl/lib/dl/func.rb
  • ext/dl/lib/dl/import.rb
  • ext/dl/lib/dl/pack.rb
  • ext/dl/lib/dl/stack.rb
  • ext/dl/lib/dl/struct.rb
  • ext/dl/lib/dl/types.rb
  • ext/dl/lib/dl/value.rb
  • ext/dl/lib/dl.rb

Constants

ALIGN_CHAR

ALIGN_CHAR

The alignment size of a char

ALIGN_DOUBLE

ALIGN_DOUBLE

The alignment size of a double

ALIGN_FLOAT

ALIGN_FLOAT

The alignment size of a float

ALIGN_INT

ALIGN_INT

The alignment size of an int

ALIGN_INTPTR_T

ALIGN_INTPTR_T

The alignment size of a intptr_t

ALIGN_LONG

ALIGN_LONG

The alignment size of a long

ALIGN_LONG_LONG

ALIGN_LONG_LONG

The alignment size of a long long

ALIGN_PTRDIFF_T

ALIGN_PTRDIFF_T

The alignment size of a ptrdiff_t

ALIGN_SHORT

ALIGN_SHORT

The alignment size of a short

ALIGN_SIZE_T

ALIGN_SIZE_T

The alignment size of a size_t

ALIGN_SSIZE_T

ALIGN_SSIZE_T

The alignment size of a ssize_t

ALIGN_UINTPTR_T

ALIGN_UINTPTR_T

The alignment size of a uintptr_t

ALIGN_VOIDP

ALIGN_VOIDP

The alignment size of a void*

BUILD_RUBY_PLATFORM

BUILD_RUBY_PLATFORM

Platform built against (i.e. “x86_64-linux”, etc.)

See also RUBY_PLATFORM

BUILD_RUBY_VERSION

BUILD_RUBY_VERSION

Ruby Version built. (i.e. “1.9.3”)

See also RUBY_VERSION

DLSTACK_SIZE

DLSTACK_SIZE

Dynamic linker stack size

MAX_CALLBACK

MAX_CALLBACK

Maximum number of callbacks

NULL
NULL

A NULL pointer

RTLD_GLOBAL

Handle flag.

The symbols defined by this library will be made available for symbol resolution of subsequently loaded libraries.

RTLD_LAZY

Handle flag.

Perform lazy binding. Only resolve symbols as the code that references them is executed. If the symbol is never referenced, then it is never resolved. (Lazy binding is only performed for function references; references to variables are always immediately bound when the library is loaded.)

RTLD_NOW

Handle flag.

If this value is specified or the environment variable LD_BIND_NOW is set to a nonempty string, all undefined symbols in the library are resolved before dlopen() returns. If this cannot be done an error is returned.

RUBY_FREE

RUBY_FREE

Address of the ruby_xfree() function

SIZEOF_CHAR

SIZEOF_CHAR

size of a char

SIZEOF_DOUBLE

SIZEOF_DOUBLE

size of a double

SIZEOF_FLOAT

SIZEOF_FLOAT

size of a float

SIZEOF_INT

SIZEOF_INT

size of an int

SIZEOF_INTPTR_T

SIZEOF_INTPTR_T

size of a intptr_t

SIZEOF_LONG

SIZEOF_LONG

size of a long

SIZEOF_LONG_LONG

SIZEOF_LONG_LONG

size of a long long

SIZEOF_PTRDIFF_T

SIZEOF_PTRDIFF_T

size of a ptrdiff_t

SIZEOF_SHORT

SIZEOF_SHORT

size of a short

SIZEOF_SIZE_T

SIZEOF_SIZE_T

size of a size_t

SIZEOF_SSIZE_T

SIZEOF_SSIZE_T

size of a ssize_t

SIZEOF_UINTPTR_T

SIZEOF_UINTPTR_T

size of a uintptr_t

SIZEOF_VOIDP

SIZEOF_VOIDP

size of a void*

TYPE_CHAR

CFunc type - char

TYPE_DOUBLE

CFunc type - double

TYPE_FLOAT

CFunc type - float

TYPE_INT

CFunc type - int

TYPE_INTPTR_T

CFunc type - intptr_t

TYPE_LONG

CFunc type - long

TYPE_LONG_LONG

CFunc type - long long

TYPE_PTRDIFF_T

CFunc type - ptrdiff_t

TYPE_SHORT

CFunc type - short

TYPE_SIZE_T

CFunc type - size_t

TYPE_SSIZE_T

CFunc type - ssize_t

TYPE_UINTPTR_T

CFunc type - uintptr_t

TYPE_VOID

CFunc type - void

TYPE_VOIDP

CFunc type - void*

Public Class Methods

dlopen(so_lib) click to toggle source

An interface to the dynamic linking loader

This is a shortcut to DL::Handle.new and takes the same arguments.

Example:

libc_so = "/lib64/libc.so.6"
=> "/lib64/libc.so.6"

libc = DL.dlopen(libc_so)
=> #<DL::Handle:0x00000000e05b00>

VALUE
rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
{
    return rb_class_new_instance(argc, argv, rb_cDLHandle);
}
dlunwrap(addr) click to toggle source

Returns the hexadecimal representation of a memory pointer address addr

Example:

lib = DL.dlopen('/lib64/libc-2.15.so')
=> #<DL::Handle:0x00000001342460>

lib['strcpy'].to_s(16)
=> "7f59de6dd240"

DL.dlunwrap(DL.dlwrap(lib['strcpy'].to_s(16)))
=> "7f59de6dd240"

VALUE
rb_dl_ptr2value(VALUE self, VALUE addr)
{
    rb_secure(4);
    return (VALUE)NUM2PTR(addr);
}
dlwrap(val) click to toggle source

Returns a memory pointer of a function's hexadecimal address location val

Example:

lib = DL.dlopen('/lib64/libc-2.15.so')
=> #<DL::Handle:0x00000001342460>

DL.dlwrap(lib['strcpy'].to_s(16))
=> 25522520

VALUE
rb_dl_value2ptr(VALUE self, VALUE val)
{
    return PTR2NUM((void*)val);
}
fiddle?() click to toggle source

Returns true if DL is using Fiddle, the libffi wrapper.

# File ext/dl/lib/dl.rb, line 12
def self.fiddle?
  Object.const_defined?(:Fiddle)
end
free(addr) click to toggle source

Free the memory at address addr

VALUE
rb_dl_free(VALUE self, VALUE addr)
{
    void *ptr = NUM2PTR(addr);

    rb_secure(4);
    ruby_xfree(ptr);
    return Qnil;
}
malloc(size) click to toggle source

Allocate size bytes of memory and return the integer memory address for the allocated memory.

VALUE
rb_dl_malloc(VALUE self, VALUE size)
{
    void *ptr;

    rb_secure(4);
    ptr = (void*)ruby_xmalloc(NUM2INT(size));
    return PTR2NUM(ptr);
}
realloc(addr, size) click to toggle source

Change the size of the memory allocated at the memory location addr to size bytes. Returns the memory address of the reallocated memory, which may be different than the address passed in.

VALUE
rb_dl_realloc(VALUE self, VALUE addr, VALUE size)
{
    void *ptr = NUM2PTR(addr);

    rb_secure(4);
    ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size));
    return PTR2NUM(ptr);
}

Public Instance Methods

remove_callback(addr, ctype = nil) click to toggle source
Alias for: remove_cdecl_callback
remove_callback_internal(proc_entry, addr_entry, addr, ctype = nil) click to toggle source
# File ext/dl/lib/dl/callback.rb, line 70
def remove_callback_internal(proc_entry, addr_entry, addr, ctype = nil)
  if DL.fiddle?
    addr = addr.to_i
    return false unless proc_entry.key?(addr)
    proc_entry.delete(addr)
    true
  else
    index = nil
    if( ctype )
      addr_entry[ctype].each_with_index{|xaddr, idx|
        if( xaddr == addr )
          index = idx
        end
      }
    else
      addr_entry.each{|ty,entry|
        entry.each_with_index{|xaddr, idx|
          if( xaddr == addr )
            index = idx
          end
        }
      }
    end
    if( index and proc_entry[ctype][index] )
      proc_entry[ctype][index] = nil
      return true
    else
      return false
    end
  end
end
remove_cdecl_callback(addr, ctype = nil) click to toggle source
# File ext/dl/lib/dl/callback.rb, line 102
def remove_cdecl_callback(addr, ctype = nil)
  remove_callback_internal(CdeclCallbackProcs, CdeclCallbackAddrs, addr, ctype)
end
Also aliased as: remove_callback
remove_stdcall_callback(addr, ctype = nil) click to toggle source
# File ext/dl/lib/dl/callback.rb, line 106
def remove_stdcall_callback(addr, ctype = nil)
  remove_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, addr, ctype)
end
set_callback(ty, argc, &cbp) click to toggle source
Alias for: set_cdecl_callback
set_callback_internal(proc_entry, addr_entry, argc, ty, abi = nil, &cbp) click to toggle source
# File ext/dl/lib/dl/callback.rb, line 30
def set_callback_internal(proc_entry, addr_entry, argc, ty, abi = nil, &cbp)
  if( argc < 0 )
    raise(ArgumentError, "arity should not be less than 0.")
  end
  addr = nil

  if DL.fiddle?
    abi ||= Fiddle::Function::DEFAULT
    closure = Fiddle::Closure::BlockCaller.new(ty, [TYPE_VOIDP] * argc, abi, &cbp)
    proc_entry[closure.to_i] = closure
    addr = closure.to_i
  else
    SEM.synchronize{
      ary = proc_entry[ty]
      (0...MAX_CALLBACK).each{|n|
        idx = (n * DLSTACK_SIZE) + argc
        if( ary[idx].nil? )
          ary[idx] = cbp
          addr = addr_entry[ty][idx]
          break
        end
      }
    }
  end

  addr
end
set_cdecl_callback(ty, argc, &cbp) click to toggle source
# File ext/dl/lib/dl/callback.rb, line 58
def set_cdecl_callback(ty, argc, &cbp)
  set_callback_internal(CdeclCallbackProcs, CdeclCallbackAddrs, argc, ty, &cbp)
end
Also aliased as: set_callback
set_stdcall_callback(ty, argc, &cbp) click to toggle source
# File ext/dl/lib/dl/callback.rb, line 62
def set_stdcall_callback(ty, argc, &cbp)
  if DL.fiddle?
    set_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, argc, ty, Fiddle::Function::STDCALL, &cbp)
  else
    set_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, argc, ty, &cbp)
  end
end


module DL::BasicTypes - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DL::BasicTypes

Adds basic type aliases to the including class for use with DL::Importer.

The aliases added are uint and u_int (unsigned int) and ulong and u_long (unsigned long)

In Files

  • ext/dl/lib/dl/types.rb


class DL::CFunc - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::CFunc

A direct accessor to a function in a C library

Example

libc_so = "/lib64/libc.so.6"
=> "/lib64/libc.so.6"
libc = DL::dlopen(libc_so)
=> #<DL::Handle:0x00000000e05b00>
@cfunc = DL::CFunc.new(libc,['strcpy'], DL::TYPE_VOIDP, 'strcpy')
=> #<DL::CFunc:0x000000012daec0 ptr=0x007f62ca5a8300 type=1 name='strcpy'>

In Files

  • ext/dl/cfunc.c

Parent

Object

Public Class Methods

last_error() click to toggle source

Returns the last error for the current executing thread

static VALUE
rb_dl_get_last_error(VALUE self)
{
    return rb_thread_local_aref(rb_thread_current(), id_last_error);
}
DL::CFunc.new(address, type=DL::TYPE_VOID, name=nil, calltype=:cdecl) click to toggle source

Create a new function that points to address with an optional return type of type, a name of name and a calltype of calltype.

static VALUE
rb_dlcfunc_initialize(int argc, VALUE argv[], VALUE self)
{
    VALUE addr, name, type, calltype, addrnum;
    struct cfunc_data *data;
    void *saddr;
    const char *sname;

    rb_scan_args(argc, argv, "13", &addr, &type, &name, &calltype);

    addrnum = rb_Integer(addr);
    saddr = (void*)(NUM2PTR(addrnum));
    sname = NIL_P(name) ? NULL : StringValuePtr(name);

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, data);
    if( data->name ) xfree(data->name);
    data->ptr  = saddr;
    data->name = sname ? strdup(sname) : 0;
    data->type = NIL_P(type) ? DLTYPE_VOID : NUM2INT(type);
    data->calltype = NIL_P(calltype) ? CFUNC_CDECL : SYM2ID(calltype);
    data->wrap = (addrnum == addr) ? 0 : addr;

    return Qnil;
}
win32_last_error() click to toggle source

Returns the last win32 error for the current executing thread

static VALUE
rb_dl_get_win32_last_error(VALUE self)
{
    return rb_thread_local_aref(rb_thread_current(), id_win32_last_error);
}

Public Instance Methods

call(ary) → some_value click to toggle source
dlcfunc[ary] → some_value

Calls the function pointer passing in ary as values to the underlying C function. The return value depends on the ctype.

static VALUE
rb_dlcfunc_call(VALUE self, VALUE ary)
{
    struct cfunc_data *cfunc;
    int i;
    DLSTACK_TYPE stack[DLSTACK_SIZE];
    VALUE result = Qnil;

    rb_secure_update(self);

    memset(stack, 0, sizeof(DLSTACK_TYPE) * DLSTACK_SIZE);
    Check_Type(ary, T_ARRAY);

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);

    if( cfunc->ptr == 0 ){
        rb_raise(rb_eDLError, "can't call null-function");
        return Qnil;
    }

    for( i = 0; i < RARRAY_LEN(ary); i++ ){
        VALUE arg;
        if( i >= DLSTACK_SIZE ){
            rb_raise(rb_eDLError, "too many arguments (stack overflow)");
        }
        arg = rb_to_int(RARRAY_PTR(ary)[i]);
        rb_check_safe_obj(arg);
        if (FIXNUM_P(arg)) {
            stack[i] = (DLSTACK_TYPE)FIX2LONG(arg);
        }
        else if (RB_TYPE_P(arg, T_BIGNUM)) {
#if SIZEOF_VOIDP == SIZEOF_LONG
            stack[i] = (DLSTACK_TYPE)rb_big2ulong_pack(arg);
#else
            stack[i] = (DLSTACK_TYPE)rb_big2ull(arg);
#endif
        }
        else {
            Check_Type(arg, T_FIXNUM);
        }
    }

    /* calltype == CFUNC_CDECL */
    if( cfunc->calltype == CFUNC_CDECL
#ifndef FUNC_STDCALL
        || cfunc->calltype == CFUNC_STDCALL
#endif
        ){
        switch( cfunc->type ){
        case DLTYPE_VOID:
#define CASE(n) case n: { \
            DECL_FUNC_CDECL(f,void,DLSTACK_PROTO##n,cfunc->ptr); \
            f(DLSTACK_ARGS##n(stack)); \
            result = Qnil; \
}
call(ary) → some_value click to toggle source
dlcfunc[ary] → some_value

Calls the function pointer passing in ary as values to the underlying C function. The return value depends on the ctype.

static VALUE
rb_dlcfunc_call(VALUE self, VALUE ary)
{
    struct cfunc_data *cfunc;
    int i;
    DLSTACK_TYPE stack[DLSTACK_SIZE];
    VALUE result = Qnil;

    rb_secure_update(self);

    memset(stack, 0, sizeof(DLSTACK_TYPE) * DLSTACK_SIZE);
    Check_Type(ary, T_ARRAY);

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);

    if( cfunc->ptr == 0 ){
        rb_raise(rb_eDLError, "can't call null-function");
        return Qnil;
    }

    for( i = 0; i < RARRAY_LEN(ary); i++ ){
        VALUE arg;
        if( i >= DLSTACK_SIZE ){
            rb_raise(rb_eDLError, "too many arguments (stack overflow)");
        }
        arg = rb_to_int(RARRAY_PTR(ary)[i]);
        rb_check_safe_obj(arg);
        if (FIXNUM_P(arg)) {
            stack[i] = (DLSTACK_TYPE)FIX2LONG(arg);
        }
        else if (RB_TYPE_P(arg, T_BIGNUM)) {
#if SIZEOF_VOIDP == SIZEOF_LONG
            stack[i] = (DLSTACK_TYPE)rb_big2ulong_pack(arg);
#else
            stack[i] = (DLSTACK_TYPE)rb_big2ull(arg);
#endif
        }
        else {
            Check_Type(arg, T_FIXNUM);
        }
    }

    /* calltype == CFUNC_CDECL */
    if( cfunc->calltype == CFUNC_CDECL
#ifndef FUNC_STDCALL
        || cfunc->calltype == CFUNC_STDCALL
#endif
        ){
        switch( cfunc->type ){
        case DLTYPE_VOID:
#define CASE(n) case n: { \
            DECL_FUNC_CDECL(f,void,DLSTACK_PROTO##n,cfunc->ptr); \
            f(DLSTACK_ARGS##n(stack)); \
            result = Qnil; \
}
calltype → symbol click to toggle source

Get the call type of this function.

static VALUE
rb_dlcfunc_calltype(VALUE self)
{
    struct cfunc_data *cfunc;

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);
    return ID2SYM(cfunc->calltype);
}
calltype = symbol click to toggle source

Set the call type for this function.

static VALUE
rb_dlcfunc_set_calltype(VALUE self, VALUE sym)
{
    struct cfunc_data *cfunc;

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);
    cfunc->calltype = SYM2ID(sym);
    return sym;
}
ctype → num click to toggle source

Get the C function return value type. See DL for a list of constants corresponding to this method's return value.

static VALUE
rb_dlcfunc_ctype(VALUE self)
{
    struct cfunc_data *cfunc;

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);
    return INT2NUM(cfunc->type);
}
ctype = type click to toggle source

Set the C function return value type to type.

static VALUE
rb_dlcfunc_set_ctype(VALUE self, VALUE ctype)
{
    struct cfunc_data *cfunc;

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);
    cfunc->type = NUM2INT(ctype);
    return ctype;
}
inspect click to toggle source

Returns a string formatted with an easily readable representation of the internal state of the DL::CFunc

static VALUE
rb_dlcfunc_inspect(VALUE self)
{
    VALUE val;
    struct cfunc_data *cfunc;

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);

    val = rb_sprintf("#<DL::CFunc:%p ptr=%p type=%d name='%s'>",
             cfunc,
             cfunc->ptr,
             cfunc->type,
             cfunc->name ? cfunc->name : "");
    OBJ_TAINT(val);
    return val;
}
name → str click to toggle source

Get the name of this function

static VALUE
rb_dlcfunc_name(VALUE self)
{
    struct cfunc_data *cfunc;

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);
    return cfunc->name ? rb_tainted_str_new2(cfunc->name) : Qnil;
}
ptr click to toggle source

Get the underlying function pointer as a DL::CPtr object.

static VALUE
rb_dlcfunc_ptr(VALUE self)
{
    struct cfunc_data *cfunc;

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);
    return PTR2NUM(cfunc->ptr);
}
ptr = pointer click to toggle source

Set the underlying function pointer to a DL::CPtr named pointer.

static VALUE
rb_dlcfunc_set_ptr(VALUE self, VALUE addr)
{
    struct cfunc_data *cfunc;

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);
    cfunc->ptr = NUM2PTR(addr);

    return Qnil;
}
to_i → integer click to toggle source

Returns the memory location of this function pointer as an integer.

static VALUE
rb_dlcfunc_to_i(VALUE self)
{
  struct cfunc_data *cfunc;

  TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);
  return PTR2NUM(cfunc->ptr);
}
inspect click to toggle source

Returns a string formatted with an easily readable representation of the internal state of the DL::CFunc

static VALUE
rb_dlcfunc_inspect(VALUE self)
{
    VALUE val;
    struct cfunc_data *cfunc;

    TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc);

    val = rb_sprintf("#<DL::CFunc:%p ptr=%p type=%d name='%s'>",
             cfunc,
             cfunc->ptr,
             cfunc->type,
             cfunc->name ? cfunc->name : "");
    OBJ_TAINT(val);
    return val;
}


module DL::CParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DL::CParser

Methods for parsing C struct and C prototype signatures.

In Files

  • ext/dl/lib/dl/cparser.rb

Public Instance Methods

parse_ctype(ty, tymap=nil) click to toggle source

Given a String of C type ty, return the corresponding DL constant.

ty can also accept an Array of C type Strings, and will returned in a corresponding Array.

If Hash tymap is provided, ty is expected to be the key, and the value will be the C type to be looked up.

Example:

parse_ctype('int')
=> DL::TYPE_INT

parse_ctype('double')
=> DL::TYPE_DOUBLE

parse_ctype('unsigned char')
=> -DL::TYPE_CHAR

# File ext/dl/lib/dl/cparser.rb, line 96
def parse_ctype(ty, tymap=nil)
  tymap ||= {}
  case ty
  when Array
    return [parse_ctype(ty[0], tymap), ty[1]]
  when "void"
    return TYPE_VOID
  when "char"
    return TYPE_CHAR
  when "unsigned char"
    return  -TYPE_CHAR
  when "short"
    return TYPE_SHORT
  when "unsigned short"
    return -TYPE_SHORT
  when "int"
    return TYPE_INT
  when "unsigned int", 'uint'
    return -TYPE_INT
  when "long"
    return TYPE_LONG
  when "unsigned long"
    return -TYPE_LONG
  when "long long"
    if( defined?(TYPE_LONG_LONG) )
      return TYPE_LONG_LONG
    else
      raise(RuntimeError, "unsupported type: #{ty}")
    end
  when "unsigned long long"
    if( defined?(TYPE_LONG_LONG) )
      return -TYPE_LONG_LONG
    else
      raise(RuntimeError, "unsupported type: #{ty}")
    end
  when "float"
    return TYPE_FLOAT
  when "double"
    return TYPE_DOUBLE
  when "size_t"
    return TYPE_SIZE_T
  when "ssize_t"
    return TYPE_SSIZE_T
  when "ptrdiff_t"
    return TYPE_PTRDIFF_T
  when "intptr_t"
    return TYPE_INTPTR_T
  when "uintptr_t"
    return TYPE_UINTPTR_T
  when /\*/, /\[\s*\]/
    return TYPE_VOIDP
  else
    if( tymap[ty] )
      return parse_ctype(tymap[ty], tymap)
    else
      raise(DLError, "unknown type: #{ty}")
    end
  end
end
parse_signature(signature, tymap=nil) click to toggle source

Parses a C prototype signature

Example:

include DL::CParser
=> Object

parse_signature('double sum(double, double)')
=> ["sum", DL::TYPE_DOUBLE, [DL::TYPE_DOUBLE, DL::TYPE_DOUBLE]]

# File ext/dl/lib/dl/cparser.rb, line 56
def parse_signature(signature, tymap=nil)
  tymap ||= {}
  signature = signature.gsub(/\s+/, " ").strip
  case signature
  when /^([\w@\*\s]+)\(([\w\*\s\,\[\]]*)\)$/
    ret = $1
    (args = $2).strip!
    ret = ret.split(/\s+/)
    args = args.split(/\s*,\s*/)
    func = ret.pop
    if( func =~ /^\*/ )
      func.gsub!(/^\*+/,"")
      ret.push("*")
    end
    ret  = ret.join(" ")
    return [func, parse_ctype(ret, tymap), args.collect{|arg| parse_ctype(arg, tymap)}]
  else
    raise(RuntimeError,"can't parse the function prototype: #{signature}")
  end
end
parse_struct_signature(signature, tymap=nil) click to toggle source

Parses a C struct's members

Example:

parse_struct_signature(['int i', 'char c'])
=> [[DL::TYPE_INT, DL::TYPE_CHAR], ["i", "c"]]

# File ext/dl/lib/dl/cparser.rb, line 11
def parse_struct_signature(signature, tymap=nil)
  if( signature.is_a?(String) )
    signature = signature.split(/\s*,\s*/)
  end
  mems = []
  tys  = []
  signature.each{|msig|
    tks = msig.split(/\s+(\*)?/)
    ty = tks[0..-2].join(" ")
    member = tks[-1]

    case ty
    when /\[(\d+)\]/
      n = $1.to_i
      ty.gsub!(/\s*\[\d+\]/,"")
      ty = [ty, n]
    when /\[\]/
      ty.gsub!(/\s*\[\]/, "*")
    end

    case member
    when /\[(\d+)\]/
      ty = [ty, $1.to_i]
      member.gsub!(/\s*\[\d+\]/,"")
    when /\[\]/
      ty = ty + "*"
      member.gsub!(/\s*\[\]/, "")
    end

    mems.push(member)
    tys.push(parse_ctype(ty,tymap))
  }
  return tys, mems
end


class DL::CPtr - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::CPtr

CPtr is a class to handle C pointers

In Files

  • ext/dl/cfunc.c

Parent

Object

Public Class Methods

DL::CPtr.to_ptr(val) → cptr click to toggle source
DL::CPtr[val] → cptr

Get the underlying pointer for ruby object val and return it as a DL::CPtr object.

static VALUE
rb_dlptr_s_to_ptr(VALUE self, VALUE val)
{
    VALUE ptr, wrap = val, vptr;

    if (RTEST(rb_obj_is_kind_of(val, rb_cIO))){
        rb_io_t *fptr;
        FILE *fp;
        GetOpenFile(val, fptr);
        fp = rb_io_stdio_file(fptr);
        ptr = rb_dlptr_new(fp, 0, NULL);
    }
    else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){
        char *str = StringValuePtr(val);
        ptr = rb_dlptr_new(str, RSTRING_LEN(val), NULL);
    }
    else if ((vptr = rb_check_funcall(val, id_to_ptr, 0, 0)) != Qundef){
        if (rb_obj_is_kind_of(vptr, rb_cDLCPtr)){
            ptr = vptr;
            wrap = 0;
        }
        else{
            rb_raise(rb_eDLError, "to_ptr should return a CPtr object");
        }
    }
    else{
        VALUE num = rb_Integer(val);
        if (num == val) wrap = 0;
        ptr = rb_dlptr_new(NUM2PTR(num), 0, NULL);
    }
    OBJ_INFECT(ptr, val);
    if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
    return ptr;
}
DL::CPtr.malloc(size, freefunc = nil) → dl cptr instance click to toggle source

Allocate size bytes of memory and associate it with an optional freefunc that will be called when the pointer is garbage collected. freefunc must be an address pointing to a function or an instance of DL::CFunc

static VALUE
rb_dlptr_s_malloc(int argc, VALUE argv[], VALUE klass)
{
    VALUE size, sym, obj, wrap = 0;
    long s;
    freefunc_t f;

    switch (rb_scan_args(argc, argv, "11", &size, &sym)) {
      case 1:
        s = NUM2LONG(size);
        f = NULL;
        break;
      case 2:
        s = NUM2LONG(size);
        f = get_freefunc(sym, &wrap);
        break;
      default:
        rb_bug("rb_dlptr_s_malloc");
    }

    obj = rb_dlptr_malloc(s,f);
    if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;

    return obj;
}
DL::CPtr.new(address) → dl_cptr click to toggle source
DL::CPtr.new(address, size) → dl_cptr
DL::CPtr.new(address, size, freefunc) → dl_cptr

Create a new pointer to address with an optional size and freefunc. freefunc will be called when the instance is garbage collected.

static VALUE
rb_dlptr_initialize(int argc, VALUE argv[], VALUE self)
{
    VALUE ptr, sym, size, wrap = 0, funcwrap = 0;
    struct ptr_data *data;
    void *p = NULL;
    freefunc_t f = NULL;
    long s = 0;

    if (rb_scan_args(argc, argv, "12", &ptr, &size, &sym) >= 1) {
        VALUE addrnum = rb_Integer(ptr);
        if (addrnum != ptr) wrap = ptr;
        p = NUM2PTR(addrnum);
    }
    if (argc >= 2) {
        s = NUM2LONG(size);
    }
    if (argc >= 3) {
        f = get_freefunc(sym, &funcwrap);
    }

    if (p) {
        TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
        if (data->ptr && data->free) {
            /* Free previous memory. Use of inappropriate initialize may cause SEGV. */
            (*(data->free))(data->ptr);
        }
        data->wrap[0] = wrap;
        data->wrap[1] = funcwrap;
        data->ptr  = p;
        data->size = s;
        data->free = f;
    }

    return Qnil;
}
DL::CPtr.to_ptr(val) → cptr click to toggle source
DL::CPtr[val] → cptr

Get the underlying pointer for ruby object val and return it as a DL::CPtr object.

static VALUE
rb_dlptr_s_to_ptr(VALUE self, VALUE val)
{
    VALUE ptr, wrap = val, vptr;

    if (RTEST(rb_obj_is_kind_of(val, rb_cIO))){
        rb_io_t *fptr;
        FILE *fp;
        GetOpenFile(val, fptr);
        fp = rb_io_stdio_file(fptr);
        ptr = rb_dlptr_new(fp, 0, NULL);
    }
    else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){
        char *str = StringValuePtr(val);
        ptr = rb_dlptr_new(str, RSTRING_LEN(val), NULL);
    }
    else if ((vptr = rb_check_funcall(val, id_to_ptr, 0, 0)) != Qundef){
        if (rb_obj_is_kind_of(vptr, rb_cDLCPtr)){
            ptr = vptr;
            wrap = 0;
        }
        else{
            rb_raise(rb_eDLError, "to_ptr should return a CPtr object");
        }
    }
    else{
        VALUE num = rb_Integer(val);
        if (num == val) wrap = 0;
        ptr = rb_dlptr_new(NUM2PTR(num), 0, NULL);
    }
    OBJ_INFECT(ptr, val);
    if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
    return ptr;
}

Public Instance Methods

ptr + n → new cptr click to toggle source

Returns a new DL::CPtr that has been advanced n bytes.

static VALUE
rb_dlptr_plus(VALUE self, VALUE other)
{
    void *ptr;
    long num, size;

    ptr = rb_dlptr2cptr(self);
    size = RPTR_DATA(self)->size;
    num = NUM2LONG(other);
    return rb_dlptr_new((char *)ptr + num, size - num, 0);
}
ptr click to toggle source

Returns a DL::CPtr that is a dereferenced pointer for this DL::CPtr. Analogous to the star operator in C.

VALUE
rb_dlptr_ptr(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    return rb_dlptr_new(*((void**)(data->ptr)),0,0);
}
ptr - n → new cptr click to toggle source

Returns a new DL::CPtr that has been moved back n bytes.

static VALUE
rb_dlptr_minus(VALUE self, VALUE other)
{
    void *ptr;
    long num, size;

    ptr = rb_dlptr2cptr(self);
    size = RPTR_DATA(self)->size;
    num = NUM2LONG(other);
    return rb_dlptr_new((char *)ptr - num, size + num, 0);
}
ref click to toggle source

Returns a DL::CPtr that is a reference pointer for this DL::CPtr. Analogous to the ampersand operator in C.

VALUE
rb_dlptr_ref(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    return rb_dlptr_new(&(data->ptr),0,0);
}
ptr <=> other → -1, 0, 1, or nil click to toggle source

Returns -1 if less than, 0 if equal to, 1 if greater than other. Returns nil if ptr cannot be compared to other.

static VALUE
rb_dlptr_cmp(VALUE self, VALUE other)
{
    void *ptr1, *ptr2;
    SIGNED_VALUE diff;

    if(!rb_obj_is_kind_of(other, rb_cDLCPtr)) return Qnil;

    ptr1 = rb_dlptr2cptr(self);
    ptr2 = rb_dlptr2cptr(other);
    diff = (SIGNED_VALUE)ptr1 - (SIGNED_VALUE)ptr2;
    if (!diff) return INT2FIX(0);
    return diff > 0 ? INT2NUM(1) : INT2NUM(-1);
}
ptr == other → true or false click to toggle source
eql?(other) → true or false

Returns true if other wraps the same pointer, otherwise returns false.

VALUE
rb_dlptr_eql(VALUE self, VALUE other)
{
    void *ptr1, *ptr2;

    if(!rb_obj_is_kind_of(other, rb_cDLCPtr)) return Qfalse;

    ptr1 = rb_dlptr2cptr(self);
    ptr2 = rb_dlptr2cptr(other);

    return ptr1 == ptr2 ? Qtrue : Qfalse;
}
ptr[index] → an_integer click to toggle source
ptr[start, length] → a_string

Returns integer stored at index. If start and length are given, a string containing the bytes from start of length length will be returned.

VALUE
rb_dlptr_aref(int argc, VALUE argv[], VALUE self)
{
    VALUE arg0, arg1;
    VALUE retval = Qnil;
    size_t offset, len;
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    if (!data->ptr) rb_raise(rb_eDLError, "NULL pointer dereference");
    switch( rb_scan_args(argc, argv, "11", &arg0, &arg1) ){
      case 1:
        offset = NUM2ULONG(arg0);
        retval = INT2NUM(*((char *)data->ptr + offset));
        break;
      case 2:
        offset = NUM2ULONG(arg0);
        len    = NUM2ULONG(arg1);
        retval = rb_tainted_str_new((char *)data->ptr + offset, len);
        break;
      default:
        rb_bug("rb_dlptr_aref()");
    }
    return retval;
}
ptr[index] = int → int click to toggle source
ptr[start, length] = string or cptr or addr → string or dl_cptr or addr

Set the value at index to int. Or, set the memory at start until length with the contents of string, the memory from dl_cptr, or the memory pointed at by the memory address addr.

VALUE
rb_dlptr_aset(int argc, VALUE argv[], VALUE self)
{
    VALUE arg0, arg1, arg2;
    VALUE retval = Qnil;
    size_t offset, len;
    void *mem;
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    if (!data->ptr) rb_raise(rb_eDLError, "NULL pointer dereference");
    switch( rb_scan_args(argc, argv, "21", &arg0, &arg1, &arg2) ){
      case 2:
        offset = NUM2ULONG(arg0);
        ((char*)data->ptr)[offset] = NUM2UINT(arg1);
        retval = arg1;
        break;
      case 3:
        offset = NUM2ULONG(arg0);
        len    = NUM2ULONG(arg1);
        if (RB_TYPE_P(arg2, T_STRING)) {
            mem = StringValuePtr(arg2);
        }
        else if( rb_obj_is_kind_of(arg2, rb_cDLCPtr) ){
            mem = rb_dlptr2cptr(arg2);
        }
        else{
            mem    = NUM2PTR(arg2);
        }
        memcpy((char *)data->ptr + offset, mem, len);
        retval = arg2;
        break;
      default:
        rb_bug("rb_dlptr_aset()");
    }
    return retval;
}
ptr == other → true or false click to toggle source
eql?(other) → true or false

Returns true if other wraps the same pointer, otherwise returns false.

VALUE
rb_dlptr_eql(VALUE self, VALUE other)
{
    void *ptr1, *ptr2;

    if(!rb_obj_is_kind_of(other, rb_cDLCPtr)) return Qfalse;

    ptr1 = rb_dlptr2cptr(self);
    ptr2 = rb_dlptr2cptr(other);

    return ptr1 == ptr2 ? Qtrue : Qfalse;
}
free click to toggle source

Get the free function for this pointer. Returns DL::CFunc or nil.

static VALUE
rb_dlptr_free_get(VALUE self)
{
    struct ptr_data *pdata;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, pdata);

    return rb_dlcfunc_new(pdata->free, DLTYPE_VOID, "free<anonymous>", CFUNC_CDECL);
}
free=(function) click to toggle source

Set the free function for this pointer to the DL::CFunc in function.

static VALUE
rb_dlptr_free_set(VALUE self, VALUE val)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    data->free = get_freefunc(val, &data->wrap[1]);

    return Qnil;
}
inspect click to toggle source

Returns a string formatted with an easily readable representation of the internal state of the DL::CPtr

static VALUE
rb_dlptr_inspect(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    return rb_sprintf("#<%"PRIsVALUE":%p ptr=%p size=%ld free=%p>",
                      rb_obj_class(self), data, data->ptr, data->size, data->free);
}
null? click to toggle source

Returns true if this is a null pointer.

VALUE
rb_dlptr_null_p(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    return data->ptr ? Qfalse : Qtrue;
}
ptr click to toggle source

Returns a DL::CPtr that is a dereferenced pointer for this DL::CPtr. Analogous to the star operator in C.

VALUE
rb_dlptr_ptr(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    return rb_dlptr_new(*((void**)(data->ptr)),0,0);
}
ref click to toggle source

Returns a DL::CPtr that is a reference pointer for this DL::CPtr. Analogous to the ampersand operator in C.

VALUE
rb_dlptr_ref(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    return rb_dlptr_new(&(data->ptr),0,0);
}
size click to toggle source

Get the size of this pointer.

static VALUE
rb_dlptr_size_get(VALUE self)
{
    return LONG2NUM(RPTR_DATA(self)->size);
}
size=(size) click to toggle source

Set the size of this pointer to size

static VALUE
rb_dlptr_size_set(VALUE self, VALUE size)
{
    RPTR_DATA(self)->size = NUM2LONG(size);
    return size;
}
to_i click to toggle source

Returns the integer memory location of this DL::CPtr.

static VALUE
rb_dlptr_to_i(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    return PTR2NUM(data->ptr);
}
to_i click to toggle source

Returns the integer memory location of this DL::CPtr.

static VALUE
rb_dlptr_to_i(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    return PTR2NUM(data->ptr);
}
to_s → string click to toggle source
to_s(len) → string

Returns the pointer contents as a string. When called with no arguments, this method will return the contents until the first NULL byte. When called with len, a string of len bytes will be returned.

static VALUE
rb_dlptr_to_s(int argc, VALUE argv[], VALUE self)
{
    struct ptr_data *data;
    VALUE arg1, val;
    int len;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    switch (rb_scan_args(argc, argv, "01", &arg1)) {
      case 0:
        val = rb_tainted_str_new2((char*)(data->ptr));
        break;
      case 1:
        len = NUM2INT(arg1);
        val = rb_tainted_str_new((char*)(data->ptr), len);
        break;
      default:
        rb_bug("rb_dlptr_to_s");
    }

    return val;
}
to_str → string click to toggle source
to_str(len) → string

Returns the pointer contents as a string. When called with no arguments, this method will return the contents with the length of this pointer's size. When called with len, a string of len bytes will be returned.

static VALUE
rb_dlptr_to_str(int argc, VALUE argv[], VALUE self)
{
    struct ptr_data *data;
    VALUE arg1, val;
    int len;

    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    switch (rb_scan_args(argc, argv, "01", &arg1)) {
      case 0:
        val = rb_tainted_str_new((char*)(data->ptr),data->size);
        break;
      case 1:
        len = NUM2INT(arg1);
        val = rb_tainted_str_new((char*)(data->ptr), len);
        break;
      default:
        rb_bug("rb_dlptr_to_str");
    }

    return val;
}
to_value click to toggle source

Cast this CPtr to a ruby object.

static VALUE
rb_dlptr_to_value(VALUE self)
{
    struct ptr_data *data;
    TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
    return (VALUE)(data->ptr);
}


class DL::CStruct - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::CStruct

C struct shell

In Files

  • ext/dl/lib/dl/struct.rb

Parent

Object

Public Class Methods

entity_class() click to toggle source

accessor to DL::CStructEntity

# File ext/dl/lib/dl/struct.rb, line 9
def CStruct.entity_class()
  CStructEntity
end


module DL::CStructBuilder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DL::CStructBuilder

Used to construct C classes (CUnion, CStruct, etc)

DL::Importer#struct and DL::Importer#union wrap this functionality in an easy-to-use manner.

In Files

  • ext/dl/lib/dl/struct.rb

Public Class Methods

create(klass, types, members) click to toggle source

Construct a new class given a C:

  • class klass (CUnion, CStruct, or other that provide an entity_class)

  • types (DL:TYPE_INT, DL::TYPE_SIZE_T, etc., see the C types constants)

  • corresponding members

DL::Importer#struct and DL::Importer#union wrap this functionality in an easy-to-use manner.

Example:

require 'dl/struct'
require 'dl/cparser'

include DL::CParser

types, members = parse_struct_signature(['int i','char c'])

MyStruct = DL::CStructBuilder.create(CUnion, types, members)

obj = MyStruct.allocate

# File ext/dl/lib/dl/struct.rb, line 50
    def create(klass, types, members)
      new_class = Class.new(klass){
        define_method(:initialize){|addr|
          @entity = klass.entity_class.new(addr, types)
          @entity.assign_names(members)
        }
        define_method(:to_ptr){ @entity }
        define_method(:to_i){ @entity.to_i }
        members.each{|name|
          define_method(name){ @entity[name] }
          define_method(name + "="){|val| @entity[name] = val }
        }
      }
      size = klass.entity_class.size(types)
      new_class.module_eval("        def new_class.size()
          #{size}
        end
        def new_class.malloc()
          addr = DL.malloc(#{size})
          new(addr)
        end
", __FILE__, __LINE__+1)
      return new_class
    end


class DL::CStructEntity - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::CStructEntity

A C struct wrapper

In Files

  • ext/dl/lib/dl/struct.rb

Parent

(DL.fiddle? ? Fiddle::Pointer : CPtr)

Included Modules

  • DL::PackInfo
  • DL::ValueUtil

Public Class Methods

malloc(types, func = nil) click to toggle source

Allocates a C struct the types provided. The C function func is called when the instance is garbage collected.

# File ext/dl/lib/dl/struct.rb, line 85
def CStructEntity.malloc(types, func = nil)
  addr = DL.malloc(CStructEntity.size(types))
  CStructEntity.new(addr, types, func)
end
new(addr, types, func = nil) click to toggle source

Wraps the C pointer addr as a C struct with the given types. The C function func is called when the instance is garbage collected.

See also DL::CPtr.new

# File ext/dl/lib/dl/struct.rb, line 115
def initialize(addr, types, func = nil)
  set_ctypes(types)
  super(addr, @size, func)
end
size(types) click to toggle source

Given types, returns the offset for the packed sizes of those types

DL::CStructEntity.size([DL::TYPE_DOUBLE, DL::TYPE_INT, DL::TYPE_CHAR,
                        DL::TYPE_VOIDP])
=> 24

# File ext/dl/lib/dl/struct.rb, line 95
def CStructEntity.size(types)
  offset = 0

  max_align = types.map { |type, count = 1|
    last_offset = offset

    align = PackInfo::ALIGN_MAP[type]
    offset = PackInfo.align(last_offset, align) +
             (PackInfo::SIZE_MAP[type] * count)

    align
  }.max

  PackInfo.align(offset, max_align)
end

Public Instance Methods

[](name) click to toggle source

Fetch struct member name

# File ext/dl/lib/dl/struct.rb, line 148
def [](name)
  idx = @members.index(name)
  if( idx.nil? )
    raise(ArgumentError, "no such member: #{name}")
  end
  ty = @ctypes[idx]
  if( ty.is_a?(Array) )
    r = super(@offset[idx], SIZE_MAP[ty[0]] * ty[1])
  else
    r = super(@offset[idx], SIZE_MAP[ty.abs])
  end
  packer = Packer.new([ty])
  val = packer.unpack([r])
  case ty
  when Array
    case ty[0]
    when TYPE_VOIDP
      val = val.collect{|v| CPtr.new(v)}
    end
  when TYPE_VOIDP
    val = CPtr.new(val[0])
  else
    val = val[0]
  end
  if( ty.is_a?(Integer) && (ty < 0) )
    return unsigned_value(val, ty)
  elsif( ty.is_a?(Array) && (ty[0] < 0) )
    return val.collect{|v| unsigned_value(v,ty[0])}
  else
    return val
  end
end
[]=(name, val) click to toggle source

Set struct member name, to value val

# File ext/dl/lib/dl/struct.rb, line 182
def []=(name, val)
  idx = @members.index(name)
  if( idx.nil? )
    raise(ArgumentError, "no such member: #{name}")
  end
  ty  = @ctypes[idx]
  packer = Packer.new([ty])
  val = wrap_arg(val, ty, [])
  buff = packer.pack([val].flatten())
  super(@offset[idx], buff.size, buff)
  if( ty.is_a?(Integer) && (ty < 0) )
    return unsigned_value(val, ty)
  elsif( ty.is_a?(Array) && (ty[0] < 0) )
    return val.collect{|v| unsigned_value(v,ty[0])}
  else
    return val
  end
end
assign_names(members) click to toggle source

Set the names of the members in this C struct

# File ext/dl/lib/dl/struct.rb, line 121
def assign_names(members)
  @members = members
end
set_ctypes(types) click to toggle source

Given types, calculate the offsets and sizes for the types in the struct.

# File ext/dl/lib/dl/struct.rb, line 127
def set_ctypes(types)
  @ctypes = types
  @offset = []
  offset = 0

  max_align = types.map { |type, count = 1|
    orig_offset = offset
    align = ALIGN_MAP[type]
    offset = PackInfo.align(orig_offset, align)

    @offset << offset

    offset += (SIZE_MAP[type] * count)

    align
  }.max

  @size = PackInfo.align(offset, max_align)
end


class DL::CUnion - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::CUnion

C union shell

In Files

  • ext/dl/lib/dl/struct.rb

Parent

Object

Public Class Methods

entity_class() click to toggle source

accessor to DL::CUnionEntity

# File ext/dl/lib/dl/struct.rb, line 17
def CUnion.entity_class()
  CUnionEntity
end


class DL::CUnionEntity - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::CUnionEntity

A C union wrapper

In Files

  • ext/dl/lib/dl/struct.rb

Parent

DL::CStructEntity

Included Modules

  • DL::PackInfo

Public Class Methods

malloc(types, func=nil) click to toggle source

Allocates a C union the types provided. The C function func is called when the instance is garbage collected.

# File ext/dl/lib/dl/struct.rb, line 212
def CUnionEntity.malloc(types, func=nil)
  addr = DL.malloc(CUnionEntity.size(types))
  CUnionEntity.new(addr, types, func)
end
size(types) click to toggle source

Given types, returns the size needed for the union.

DL::CUnionEntity.size([DL::TYPE_DOUBLE, DL::TYPE_INT, DL::TYPE_CHAR,
                       DL::TYPE_VOIDP])
=> 8

# File ext/dl/lib/dl/struct.rb, line 222
def CUnionEntity.size(types)
  types.map { |type, count = 1|
    PackInfo::SIZE_MAP[type] * count
  }.max
end

Public Instance Methods

set_ctypes(types) click to toggle source

Given types, calculate the necessary offset and for each union member

# File ext/dl/lib/dl/struct.rb, line 229
def set_ctypes(types)
  @ctypes = types
  @offset = Array.new(types.length, 0)
  @size   = self.class.size types
end


class DL::CarriedFunction - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::CarriedFunction

In Files

  • ext/dl/lib/dl/func.rb

Parent

DL::Function

Public Class Methods

new(cfunc, argtypes, n) click to toggle source
# File ext/dl/lib/dl/func.rb, line 221
def initialize(cfunc, argtypes, n)
  super(cfunc, argtypes)
  @carrier = []
  @index = n
  @mutex = Mutex.new
end

Public Instance Methods

bind_at_call(&block) click to toggle source
# File ext/dl/lib/dl/func.rb, line 236
def bind_at_call(&block)
  userdata = @carrier[-1]
  userdata[0].push(block)
  bind{|*args|
    ptr = args[@index]
    if( !ptr )
      raise(RuntimeError, "The index of userdata should be lower than #{args.size}.")
    end
    userdata = dlunwrap(Integer(ptr))
    args[@index] = userdata[1]
    userdata[0][0].call(*args)
  }
  @mutex.unlock()
end
create_carrier(data) click to toggle source
# File ext/dl/lib/dl/func.rb, line 228
def create_carrier(data)
  ary = []
  userdata = [ary, data]
  @mutex.lock()
  @carrier.push(userdata)
  return dlwrap(userdata)
end


class DL::CompositeHandler - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::CompositeHandler

In Files

  • ext/dl/lib/dl/import.rb

Parent

Object

Public Class Methods

new(handlers) click to toggle source
# File ext/dl/lib/dl/import.rb, line 8
def initialize(handlers)
  @handlers = handlers
end

Public Instance Methods

[](symbol) click to toggle source
# File ext/dl/lib/dl/import.rb, line 29
def [](symbol)
  sym(symbol)
end
handlers() click to toggle source
# File ext/dl/lib/dl/import.rb, line 12
def handlers()
  @handlers
end
sym(symbol) click to toggle source
# File ext/dl/lib/dl/import.rb, line 16
def sym(symbol)
  @handlers.each{|handle|
    if( handle )
      begin
        addr = handle.sym(symbol)
        return addr
      rescue DLError
      end
    end
  }
  return nil
end


class DL::DLError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::DLError

standard dynamic load exception

In Files

  • ext/dl/cfunc.c

Parent

StandardError


class DL::DLTypeError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::DLTypeError

dynamic load incorrect type exception

In Files

  • ext/dl/cfunc.c

Parent

DL::DLError


class DL::Function - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::Function

In Files

  • ext/dl/lib/dl/func.rb

Parent

parent

Included Modules

  • DL
  • DL::ValueUtil

Public Class Methods

new(cfunc, argtypes, abi = nil, &block) click to toggle source
# File ext/dl/lib/dl/func.rb, line 51
def initialize cfunc, argtypes, abi = nil, &block
  if DL.fiddle?
    abi ||= CALL_TYPE_TO_ABI[(cfunc.calltype rescue nil)]
    if block_given?
      @cfunc = Class.new(FiddleClosureCFunc) {
        define_method(:call, block)
      }.new(cfunc.ctype, argtypes, abi, cfunc.name)
    else
      @cfunc  = cfunc
    end

    @args   = argtypes
    super(@cfunc, @args.reject { |x| x == TYPE_VOID }, cfunc.ctype, abi)
  else
    @cfunc = cfunc
    @stack = Stack.new(argtypes.collect{|ty| ty.abs})
    if( @cfunc.ctype < 0 )
      @cfunc.ctype = @cfunc.ctype.abs
      @unsigned = true
    else
      @unsigned = false
    end
    if block_given?
      bind(&block)
    end
  end
end

Public Instance Methods

bind(&block) click to toggle source
# File ext/dl/lib/dl/func.rb, line 117
def bind(&block)
  if DL.fiddle?
    @cfunc = Class.new(FiddleClosureCFunc) {
      def initialize ctype, args, abi, name, block
        super(ctype, args, abi, name)
        @block = block
      end

      def call *args
        @block.call(*args)
      end
    }.new(@cfunc.ctype, @args, abi, name, block)
    @ptr = @cfunc
    return nil
  else
    if( !block )
      raise(RuntimeError, "block must be given.")
    end
    unless block.lambda?
      block = Class.new(self.class){define_method(:call, block); def initialize(obj); obj.instance_variables.each{|s| instance_variable_set(s, obj.instance_variable_get(s))}; end}.new(self).method(:call)
    end
    if( @cfunc.ptr == 0 )
      cb = Proc.new{|*args|
        ary = @stack.unpack(args)
        @stack.types.each_with_index{|ty, idx|
          case ty
          when TYPE_VOIDP
            ary[idx] = CPtr.new(ary[idx])
          end
        }
        r = block.call(*ary)
        wrap_arg(r, @cfunc.ctype, [])
      }
      case @cfunc.calltype
      when :cdecl
        @cfunc.ptr = set_cdecl_callback(@cfunc.ctype, @stack.size, &cb)
      when :stdcall
        @cfunc.ptr = set_stdcall_callback(@cfunc.ctype, @stack.size, &cb)
      else
        raise(RuntimeError, "unsupported calltype: #{@cfunc.calltype}")
      end
      if( @cfunc.ptr == 0 )
        raise(RuntimeException, "can't bind C function.")
      end
    end
  end
end
bind_at_call(&block) click to toggle source
# File ext/dl/lib/dl/func.rb, line 202
def bind_at_call(&block)
  bind(&block)
end
bound?() click to toggle source
# File ext/dl/lib/dl/func.rb, line 198
def bound?()
  @cfunc.ptr != 0
end
call(*args, &block) click to toggle source
# File ext/dl/lib/dl/func.rb, line 87
def call(*args, &block)
  if DL.fiddle?
    if block_given?
      args.find { |a| DL::Function === a }.bind_at_call(&block)
    end
    super
  else
    funcs = []
    if $SAFE >= 1 && args.any? { |x| x.tainted? }
      raise SecurityError, "tainted parameter not allowed"
    end
    _args = wrap_args(args, @stack.types, funcs, &block)
    r = @cfunc.call(@stack.pack(_args))
    funcs.each{|f| f.unbind_at_call()}
    return wrap_result(r)
  end
end
name() click to toggle source
# File ext/dl/lib/dl/func.rb, line 83
def name
  @cfunc.name
end
to_i() click to toggle source
# File ext/dl/lib/dl/func.rb, line 79
def to_i()
  @cfunc.to_i
end
unbind() click to toggle source
# File ext/dl/lib/dl/func.rb, line 165
def unbind()
  if DL.fiddle? then
    if @cfunc.kind_of?(Fiddle::Closure) and @cfunc.ptr != 0 then
      call_type = case abi
                  when CALL_TYPE_TO_ABI[nil]
                    nil
                  when CALL_TYPE_TO_ABI[:stdcall]
                    :stdcall
                  else
                    raise(RuntimeError, "unsupported abi: #{abi}")
                  end
      @cfunc = CFunc.new(0, @cfunc.ctype, name, call_type)
      return 0
    elsif @cfunc.ptr != 0 then
      @cfunc.ptr = 0
      return 0
    else
      return nil
    end
  end
  if( @cfunc.ptr != 0 )
    case @cfunc.calltype
    when :cdecl
      remove_cdecl_callback(@cfunc.ptr, @cfunc.ctype)
    when :stdcall
      remove_stdcall_callback(@cfunc.ptr, @cfunc.ctype)
    else
      raise(RuntimeError, "unsupported calltype: #{@cfunc.calltype}")
    end
    @cfunc.ptr = 0
  end
end
unbind_at_call() click to toggle source
# File ext/dl/lib/dl/func.rb, line 206
def unbind_at_call()
end
wrap_result(r) click to toggle source
# File ext/dl/lib/dl/func.rb, line 105
def wrap_result(r)
  case @cfunc.ctype
  when TYPE_VOIDP
    r = CPtr.new(r)
  else
    if( @unsigned )
      r = unsigned_value(r, @cfunc.ctype)
    end
  end
  r
end


class DL::Handle - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::Handle

The DL::Handle is the manner to access the dynamic library

Example

Setup

libc_so = "/lib64/libc.so.6"
=> "/lib64/libc.so.6"
@handle = DL::Handle.new(libc_so)
=> #<DL::Handle:0x00000000d69ef8>

Setup, with flags

libc_so = "/lib64/libc.so.6"
=> "/lib64/libc.so.6"
@handle = DL::Handle.new(libc_so, DL::RTLD_LAZY | DL::RTLD_GLOBAL)
=> #<DL::Handle:0x00000000d69ef8>

Addresses to symbols

strcpy_addr = @handle['strcpy']
=> 140062278451968

or

strcpy_addr = @handle.sym('strcpy')
=> 140062278451968

In Files

  • ext/dl/cfunc.c

Parent

Object

Constants

DEFAULT

DEFAULT

A predefined pseudo-handle of RTLD_DEFAULT

Which will find the first occurrence of the desired symbol using the default library search order

NEXT

NEXT

A predefined pseudo-handle of RTLD_NEXT

Which will find the next occurrence of a function in the search order after the current library.

Public Class Methods

sym(name) click to toggle source

Get the address as an Integer for the function named name.

VALUE
rb_dlhandle_s_sym(VALUE self, VALUE sym)
{
    return dlhandle_sym(RTLD_NEXT, StringValueCStr(sym));
}
initialize(lib = nil, flags = DL::RTLD_LAZY | DL::RTLD_GLOBAL) click to toggle source

Create a new handler that opens library named lib with flags. If no library is specified, RTLD_DEFAULT is used.

VALUE
rb_dlhandle_initialize(int argc, VALUE argv[], VALUE self)
{
    void *ptr;
    struct dl_handle *dlhandle;
    VALUE lib, flag;
    char  *clib;
    int   cflag;
    const char *err;

    switch( rb_scan_args(argc, argv, "02", &lib, &flag) ){
      case 0:
        clib = NULL;
        cflag = RTLD_LAZY | RTLD_GLOBAL;
        break;
      case 1:
        clib = NIL_P(lib) ? NULL : StringValuePtr(lib);
        cflag = RTLD_LAZY | RTLD_GLOBAL;
        break;
      case 2:
        clib = NIL_P(lib) ? NULL : StringValuePtr(lib);
        cflag = NUM2INT(flag);
        break;
      default:
        rb_bug("rb_dlhandle_new");
    }

    rb_secure(2);

#if defined(_WIN32)
    if( !clib ){
        HANDLE rb_libruby_handle(void);
        ptr = rb_libruby_handle();
    }
    else if( STRCASECMP(clib, "libc") == 0
# ifdef RUBY_COREDLL
             || STRCASECMP(clib, RUBY_COREDLL) == 0
             || STRCASECMP(clib, RUBY_COREDLL".dll") == 0
# endif
        ){
# ifdef _WIN32_WCE
        ptr = dlopen("coredll.dll", cflag);
# else
        ptr = w32_coredll();
# endif
    }
    else
#endif
        ptr = dlopen(clib, cflag);
#if defined(HAVE_DLERROR)
    if( !ptr && (err = dlerror()) ){
        rb_raise(rb_eDLError, "%s", err);
    }
#else
    if( !ptr ){
        err = dlerror();
        rb_raise(rb_eDLError, "%s", err);
    }
#endif
    TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle);
    if( dlhandle->ptr && dlhandle->open && dlhandle->enable_close ){
        dlclose(dlhandle->ptr);
    }
    dlhandle->ptr = ptr;
    dlhandle->open = 1;
    dlhandle->enable_close = 0;

    if( rb_block_given_p() ){
        rb_ensure(rb_yield, self, rb_dlhandle_close, self);
    }

    return Qnil;
}
sym(name) click to toggle source
Document-method: []

Get the address as an Integer for the function named name.

VALUE
rb_dlhandle_s_sym(VALUE self, VALUE sym)
{
    return dlhandle_sym(RTLD_NEXT, StringValueCStr(sym));
}

Public Instance Methods

sym(name) click to toggle source

Get the address as an Integer for the function named name.

VALUE
rb_dlhandle_sym(VALUE self, VALUE sym)
{
    struct dl_handle *dlhandle;

    TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle);
    if( ! dlhandle->open ){
        rb_raise(rb_eDLError, "closed handle");
    }

    return dlhandle_sym(dlhandle->ptr, StringValueCStr(sym));
}
close click to toggle source

Close this DL::Handle. Calling close more than once will raise a DL::DLError exception.

VALUE
rb_dlhandle_close(VALUE self)
{
    struct dl_handle *dlhandle;

    TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle);
    if(dlhandle->open) {
        int ret = dlclose(dlhandle->ptr);
        dlhandle->open = 0;

        /* Check dlclose for successful return value */
        if(ret) {
#if defined(HAVE_DLERROR)
            rb_raise(rb_eDLError, "%s", dlerror());
#else
            rb_raise(rb_eDLError, "could not close handle");
#endif
        }
        return INT2NUM(ret);
    }
    rb_raise(rb_eDLError, "dlclose() called too many times");

    UNREACHABLE;
}
close_enabled? click to toggle source

Returns true if dlclose() will be called when this DL::Handle is garbage collected.

static VALUE
rb_dlhandle_close_enabled_p(VALUE self)
{
    struct dl_handle *dlhandle;

    TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle);

    if(dlhandle->enable_close) return Qtrue;
    return Qfalse;
}
disable_close click to toggle source

Disable a call to dlclose() when this DL::Handle is garbage collected.

VALUE
rb_dlhandle_disable_close(VALUE self)
{
    struct dl_handle *dlhandle;

    TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle);
    dlhandle->enable_close = 0;
    return Qnil;
}
enable_close click to toggle source

Enable a call to dlclose() when this DL::Handle is garbage collected.

VALUE
rb_dlhandle_enable_close(VALUE self)
{
    struct dl_handle *dlhandle;

    TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle);
    dlhandle->enable_close = 1;
    return Qnil;
}
sym(name) click to toggle source
Document-method: []

Get the address as an Integer for the function named name.

VALUE
rb_dlhandle_sym(VALUE self, VALUE sym)
{
    struct dl_handle *dlhandle;

    TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle);
    if( ! dlhandle->open ){
        rb_raise(rb_eDLError, "closed handle");
    }

    return dlhandle_sym(dlhandle->ptr, StringValueCStr(sym));
}
to_i click to toggle source

Returns the memory address for this handle.

VALUE
rb_dlhandle_to_i(VALUE self)
{
    struct dl_handle *dlhandle;

    TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle);
    return PTR2NUM(dlhandle);
}


module DL::Importer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DL::Importer

DL::Importer includes the means to dynamically load libraries and build modules around them including calling extern functions within the C library that has been loaded.

Example

require 'dl'
require 'dl/import'

module LibSum
  extend DL::Importer
  dlload './libsum.so'
  extern 'double sum(double*, int)'
  extern 'double split(double)'
end

In Files

  • ext/dl/lib/dl/import.rb

Included Modules

  • DL
  • DL::CParser

Public Instance Methods

[](name) click to toggle source
# File ext/dl/lib/dl/import.rb, line 203
def [](name)
  @func_map[name]
end
bind(signature, *opts, &blk) click to toggle source
# File ext/dl/lib/dl/import.rb, line 154
    def bind(signature, *opts, &blk)
      @type_alias ||= nil
      name, ctype, argtype = parse_signature(signature, @type_alias)
      h = parse_bind_options(opts)
      case h[:callback_type]
      when :bind, nil
        f = bind_function(name, ctype, argtype, h[:call_type], &blk)
      when :temp, :temporal
        f = create_temp_function(name, ctype, argtype, h[:call_type])
      when :carried
        f = create_carried_function(name, ctype, argtype, h[:call_type], h[:carrier])
      else
        raise(RuntimeError, "unknown callback type: #{h[:callback_type]}")
      end
      @func_map[name] = f
      #define_method(name){|*args,&block| f.call(*args,&block)}
      begin
        /^(.+?):(\d+)/ =~ caller.first
        file, line = $1, $2.to_i
      rescue
        file, line = __FILE__, __LINE__+3
      end
      module_eval("        def #{name}(*args,&block)
          @func_map['#{name}'].call(*args,&block)
        end
", file, line)
      module_function(name)
      f
    end
bind_function(name, ctype, argtype, call_type = nil, &block) click to toggle source
# File ext/dl/lib/dl/import.rb, line 244
def bind_function(name, ctype, argtype, call_type = nil, &block)
  if DL.fiddle?
    klass = Function.instance_eval { class_fiddle_closure_cfunc }
    abi = Function.instance_eval { call_type_to_abi(call_type) }
    closure = Class.new(klass) {
      define_method(:call, block)
    }.new(ctype, argtype, abi, name)

    Function.new(closure, argtype, abi)
  else
    f = Function.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype)
    f.bind(&block)
    f
  end
end
create_carried_function(name, ctype, argtype, call_type = nil, n = 0) click to toggle source
# File ext/dl/lib/dl/import.rb, line 264
def create_carried_function(name, ctype, argtype, call_type = nil, n = 0)
  CarriedFunction.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype, n)
end
create_temp_function(name, ctype, argtype, call_type = nil) click to toggle source
# File ext/dl/lib/dl/import.rb, line 260
def create_temp_function(name, ctype, argtype, call_type = nil)
  TempFunction.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype)
end
create_value(ty, val=nil) click to toggle source
# File ext/dl/lib/dl/import.rb, line 207
def create_value(ty, val=nil)
  s = struct([ty + " value"])
  ptr = s.malloc()
  if( val )
    ptr.value = val
  end
  return ptr
end
Also aliased as: value
dlload(*libs) click to toggle source
# File ext/dl/lib/dl/import.rb, line 55
def dlload(*libs)
  handles = libs.collect{|lib|
    case lib
    when nil
      nil
    when Handle
      lib
    when Importer
      lib.handlers
    else
      begin
        DL.dlopen(lib)
      rescue DLError
        raise(DLError, "can't load #{lib}")
      end
    end
  }.flatten()
  @handler = CompositeHandler.new(handles)
  @func_map = {}
  @type_alias = {}
end
extern(signature, *opts) click to toggle source
# File ext/dl/lib/dl/import.rb, line 131
    def extern(signature, *opts)
      @type_alias ||= nil
      symname, ctype, argtype = parse_signature(signature, @type_alias)
      opt = parse_bind_options(opts)
      f = import_function(symname, ctype, argtype, opt[:call_type])
      name = symname.gsub(/@.+/,'')
      @func_map[name] = f
      # define_method(name){|*args,&block| f.call(*args,&block)}
      begin
        /^(.+?):(\d+)/ =~ caller.first
        file, line = $1, $2.to_i
      rescue
        file, line = __FILE__, __LINE__+3
      end
      module_eval("        def #{name}(*args, &block)
          @func_map['#{name}'].call(*args,&block)
        end
", file, line)
      module_function(name)
      f
    end
handler() click to toggle source
# File ext/dl/lib/dl/import.rb, line 223
def handler
  defined?(@handler) or raise "call dlload before importing symbols and functions"
  @handler
end
import_function(name, ctype, argtype, call_type = nil) click to toggle source
# File ext/dl/lib/dl/import.rb, line 236
def import_function(name, ctype, argtype, call_type = nil)
  addr = handler.sym(name)
  if( !addr )
    raise(DLError, "cannot find the function: #{name}()")
  end
  Function.new(CFunc.new(addr, ctype, name, call_type || :cdecl), argtype)
end
import_symbol(name) click to toggle source
# File ext/dl/lib/dl/import.rb, line 228
def import_symbol(name)
  addr = handler.sym(name)
  if( !addr )
    raise(DLError, "cannot find the symbol: #{name}")
  end
  CPtr.new(addr)
end
import_value(ty, addr) click to toggle source
# File ext/dl/lib/dl/import.rb, line 217
def import_value(ty, addr)
  s = struct([ty + " value"])
  ptr = s.new(addr)
  return ptr
end
sizeof(ty) click to toggle source
# File ext/dl/lib/dl/import.rb, line 81
def sizeof(ty)
  @type_alias ||= nil
  case ty
  when String
    ty = parse_ctype(ty, @type_alias).abs()
    case ty
    when TYPE_CHAR
      return SIZEOF_CHAR
    when TYPE_SHORT
      return SIZEOF_SHORT
    when TYPE_INT
      return SIZEOF_INT
    when TYPE_LONG
      return SIZEOF_LONG
    when TYPE_LONG_LONG
      return SIZEOF_LONG_LON
    when TYPE_FLOAT
      return SIZEOF_FLOAT
    when TYPE_DOUBLE
      return SIZEOF_DOUBLE
    when TYPE_VOIDP
      return SIZEOF_VOIDP
    else
      raise(DLError, "unknown type: #{ty}")
    end
  when Class
    if( ty.instance_methods().include?(:to_ptr) )
      return ty.size()
    end
  end
  return CPtr[ty].size()
end
struct(signature) click to toggle source

Creates a class to wrap the C struct described by signature.

MyStruct = struct ['int i', 'char c']
# File ext/dl/lib/dl/import.rb, line 188
def struct(signature)
  @type_alias ||= nil
  tys, mems = parse_struct_signature(signature, @type_alias)
  DL::CStructBuilder.create(CStruct, tys, mems)
end
typealias(alias_type, orig_type) click to toggle source
# File ext/dl/lib/dl/import.rb, line 77
def typealias(alias_type, orig_type)
  @type_alias[alias_type] = orig_type
end
union(signature) click to toggle source

Creates a class to wrap the C union described by signature.

MyUnion = union ['int i', 'char c']
# File ext/dl/lib/dl/import.rb, line 197
def union(signature)
  @type_alias ||= nil
  tys, mems = parse_struct_signature(signature, @type_alias)
  DL::CStructBuilder.create(CUnion, tys, mems)
end
value(ty, val=nil) click to toggle source
Alias for: create_value


module DL::PackInfo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DL::PackInfo

In Files

  • ext/dl/lib/dl/pack.rb

Constants

ALIGN_MAP
PACK_MAP
SIZE_MAP

Public Class Methods

align(addr, align) click to toggle source
# File ext/dl/lib/dl/pack.rb, line 52
def align(addr, align)
  d = addr % align
  if( d == 0 )
    addr
  else
    addr + (align - d)
  end
end


class DL::Packer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::Packer

In Files

  • ext/dl/lib/dl/pack.rb

Parent

Object

Included Modules

  • DL::PackInfo

Public Class Methods

[](*types) click to toggle source
# File ext/dl/lib/dl/pack.rb, line 66
def self.[](*types)
  new(types)
end
new(types) click to toggle source
# File ext/dl/lib/dl/pack.rb, line 70
def initialize(types)
  parse_types(types)
end

Public Instance Methods

pack(ary) click to toggle source
# File ext/dl/lib/dl/pack.rb, line 78
def pack(ary)
  case SIZEOF_VOIDP
  when SIZEOF_LONG
    ary.pack(@template)
  when SIZEOF_LONG_LONG
    ary.pack(@template)
  else
    raise(RuntimeError, "sizeof(void*)?")
  end
end
size() click to toggle source
# File ext/dl/lib/dl/pack.rb, line 74
def size()
  @size
end
unpack(ary) click to toggle source
# File ext/dl/lib/dl/pack.rb, line 89
def unpack(ary)
  case SIZEOF_VOIDP
  when SIZEOF_LONG
    ary.join().unpack(@template)
  when SIZEOF_LONG_LONG
    ary.join().unpack(@template)
  else
    raise(RuntimeError, "sizeof(void*)?")
  end
end


class DL::Stack - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::Stack

In Files

  • ext/dl/lib/dl/stack.rb

Parent

Object

Constants

ALIGN_MAP
PACK_MAP
SIZE_MAP

Public Class Methods

[](*types) click to toggle source
# File ext/dl/lib/dl/stack.rb, line 5
def self.[](*types)
  new(types)
end
new(types) click to toggle source
# File ext/dl/lib/dl/stack.rb, line 9
def initialize(types)
  parse_types(types)
end

Public Instance Methods

pack(ary) click to toggle source
# File ext/dl/lib/dl/stack.rb, line 21
def pack(ary)
  case SIZEOF_VOIDP
  when SIZEOF_LONG
    ary.pack(@template).unpack('l!*')
  when SIZEOF_LONG_LONG
    ary.pack(@template).unpack('q*')
  else
    raise(RuntimeError, "sizeof(void*)?")
  end
end
size() click to toggle source
# File ext/dl/lib/dl/stack.rb, line 13
def size()
  @size
end
types() click to toggle source
# File ext/dl/lib/dl/stack.rb, line 17
def types()
  @types
end
unpack(ary) click to toggle source
# File ext/dl/lib/dl/stack.rb, line 32
def unpack(ary)
  case SIZEOF_VOIDP
  when SIZEOF_LONG
    ary.pack('l!*').unpack(@template)
  when SIZEOF_LONG_LONG
    ary.pack('q*').unpack(@template)
  else
    raise(RuntimeError, "sizeof(void*)?")
  end
end


class DL::TempFunction - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DL::TempFunction

In Files

  • ext/dl/lib/dl/func.rb

Parent

DL::Function

Public Instance Methods

bind_at_call(&block) click to toggle source
# File ext/dl/lib/dl/func.rb, line 211
def bind_at_call(&block)
  bind(&block)
end
unbind_at_call() click to toggle source
# File ext/dl/lib/dl/func.rb, line 215
def unbind_at_call()
  unbind()
end


module DL::ValueUtil - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DL::ValueUtil

In Files

  • ext/dl/lib/dl/value.rb

Public Instance Methods

signed_value(val, ty) click to toggle source
# File ext/dl/lib/dl/value.rb, line 22
def signed_value(val, ty)
  case ty.abs
  when TYPE_CHAR
    [val].pack("C").unpack("c")[0]
  when TYPE_SHORT
    [val].pack("S!").unpack("s!")[0]
  when TYPE_INT
    [val].pack("I!").unpack("i!")[0]
  when TYPE_LONG
    [val].pack("L!").unpack("l!")[0]
  when TYPE_LONG_LONG
    [val].pack("Q").unpack("q")[0]
  else
    val
  end
end
unsigned_value(val, ty) click to toggle source
# File ext/dl/lib/dl/value.rb, line 5
def unsigned_value(val, ty)
  case ty.abs
  when TYPE_CHAR
    [val].pack("c").unpack("C")[0]
  when TYPE_SHORT
    [val].pack("s!").unpack("S!")[0]
  when TYPE_INT
    [val].pack("i!").unpack("I!")[0]
  when TYPE_LONG
    [val].pack("l!").unpack("L!")[0]
  when TYPE_LONG_LONG
    [val].pack("q").unpack("Q")[0]
  else
    val
  end
end
wrap_arg(arg, ty, funcs = [], &block) click to toggle source
# File ext/dl/lib/dl/value.rb, line 48
def wrap_arg(arg, ty, funcs = [], &block)
    require 'dl/func'

    funcs ||= []
    case arg
    when nil
      return 0
    when CPtr
      return arg.to_i
    when IO
      case ty
      when TYPE_VOIDP
        return CPtr[arg].to_i
      else
        return arg.to_i
      end
    when Function
      if( block )
        arg.bind_at_call(&block)
        funcs.push(arg)
      elsif !arg.bound?
        raise(RuntimeError, "block must be given.")
      end
      return arg.to_i
    when String
      if( ty.is_a?(Array) )
        return arg.unpack('C*')
      else
        case SIZEOF_VOIDP
        when SIZEOF_LONG
          return [arg].pack("p").unpack("l!")[0]
        when SIZEOF_LONG_LONG
          return [arg].pack("p").unpack("q")[0]
        else
          raise(RuntimeError, "sizeof(void*)?")
        end
      end
    when Float, Integer
      return arg
    when Array
      if( ty.is_a?(Array) ) # used only by struct
        case ty[0]
        when TYPE_VOIDP
          return arg.collect{|v| Integer(v)}
        when TYPE_CHAR
          if( arg.is_a?(String) )
            return val.unpack('C*')
          end
        end
        return arg
      else
        return arg
      end
    else
      if( arg.respond_to?(:to_ptr) )
        return arg.to_ptr.to_i
      else
        begin
          return Integer(arg)
        rescue
          raise(ArgumentError, "unknown argument type: #{arg.class}")
        end
      end
    end
end
wrap_args(args, tys, funcs, &block) click to toggle source
# File ext/dl/lib/dl/value.rb, line 39
def wrap_args(args, tys, funcs, &block)
  result = []
  tys ||= []
  args.each_with_index{|arg, idx|
    result.push(wrap_arg(arg, tys[idx], funcs, &block))
  }
  result
end


module DL::Win32Types - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DL::Win32Types

Adds Windows type aliases to the including class for use with DL::Importer.

The aliases added are:

  • ATOM

  • BOOL

  • BYTE

  • DWORD

  • DWORD32

  • DWORD64

  • HANDLE

  • HDC

  • HINSTANCE

  • HWND

  • LPCSTR

  • LPSTR

  • PBYTE

  • PDWORD

  • PHANDLE

  • PVOID

  • PWORD

  • UCHAR

  • UINT

  • ULONG

  • WORD

In Files

  • ext/dl/lib/dl/types.rb


module DRb - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DRb

Overview

dRuby is a distributed object system for Ruby. It is written in pure Ruby and uses its own protocol. No add-in services are needed beyond those provided by the Ruby runtime, such as TCP sockets. It does not rely on or interoperate with other distributed object systems such as CORBA, RMI, or .NET.

dRuby allows methods to be called in one Ruby process upon a Ruby object located in another Ruby process, even on another machine. References to objects can be passed between processes. Method arguments and return values are dumped and loaded in marshalled format. All of this is done transparently to both the caller of the remote method and the object that it is called upon.

An object in a remote process is locally represented by a DRb::DRbObject instance. This acts as a sort of proxy for the remote object. Methods called upon this DRbObject instance are forwarded to its remote object. This is arranged dynamically at run time. There are no statically declared interfaces for remote objects, such as CORBA's IDL.

dRuby calls made into a process are handled by a DRb::DRbServer instance within that process. This reconstitutes the method call, invokes it upon the specified local object, and returns the value to the remote caller. Any object can receive calls over dRuby. There is no need to implement a special interface, or mixin special functionality. Nor, in the general case, does an object need to explicitly register itself with a DRbServer in order to receive dRuby calls.

One process wishing to make dRuby calls upon another process must somehow obtain an initial reference to an object in the remote process by some means other than as the return value of a remote method call, as there is initially no remote object reference it can invoke a method upon. This is done by attaching to the server by URI. Each DRbServer binds itself to a URI such as 'druby://example.com:8787'. A DRbServer can have an object attached to it that acts as the server's front object. A DRbObject can be explicitly created from the server's URI. This DRbObject's remote object will be the server's front object. This front object can then return references to other Ruby objects in the DRbServer's process.

Method calls made over dRuby behave largely the same as normal Ruby method calls made within a process. Method calls with blocks are supported, as are raising exceptions. In addition to a method's standard errors, a dRuby call may also raise one of the dRuby-specific errors, all of which are subclasses of DRb::DRbError.

Any type of object can be passed as an argument to a dRuby call or returned as its return value. By default, such objects are dumped or marshalled at the local end, then loaded or unmarshalled at the remote end. The remote end therefore receives a copy of the local object, not a distributed reference to it; methods invoked upon this copy are executed entirely in the remote process, not passed on to the local original. This has semantics similar to pass-by-value.

However, if an object cannot be marshalled, a dRuby reference to it is passed or returned instead. This will turn up at the remote end as a DRbObject instance. All methods invoked upon this remote proxy are forwarded to the local object, as described in the discussion of DRbObjects. This has semantics similar to the normal Ruby pass-by-reference.

The easiest way to signal that we want an otherwise marshallable object to be passed or returned as a DRbObject reference, rather than marshalled and sent as a copy, is to include the DRb::DRbUndumped mixin module.

dRuby supports calling remote methods with blocks. As blocks (or rather the Proc objects that represent them) are not marshallable, the block executes in the local, not the remote, context. Each value yielded to the block is passed from the remote object to the local block, then the value returned by each block invocation is passed back to the remote execution context to be collected, before the collected values are finally returned to the local context as the return value of the method invocation.

Examples of usage

For more dRuby samples, see the samples directory in the full dRuby distribution.

dRuby in client/server mode

This illustrates setting up a simple client-server drb system. Run the server and client code in different terminals, starting the server code first.

Server code

require 'drb/drb'

# The URI for the server to connect to
URI="druby://localhost:8787"

class TimeServer

  def get_current_time
    return Time.now
  end

end

# The object that handles requests on the server
FRONT_OBJECT=TimeServer.new

$SAFE = 1   # disable eval() and friends

DRb.start_service(URI, FRONT_OBJECT)
# Wait for the drb server thread to finish before exiting.
DRb.thread.join

Client code

require 'drb/drb'

# The URI to connect to
SERVER_URI="druby://localhost:8787"

# Start a local DRbServer to handle callbacks.
#
# Not necessary for this small example, but will be required
# as soon as we pass a non-marshallable object as an argument
# to a dRuby call.
DRb.start_service

timeserver = DRbObject.new_with_uri(SERVER_URI)
puts timeserver.get_current_time

Remote objects under dRuby

This example illustrates returning a reference to an object from a dRuby call. The Logger instances live in the server process. References to them are returned to the client process, where methods can be invoked upon them. These methods are executed in the server process.

Server code

require 'drb/drb'

URI="druby://localhost:8787"

class Logger

    # Make dRuby send Logger instances as dRuby references,
    # not copies.
    include DRb::DRbUndumped

    def initialize(n, fname)
        @name = n
        @filename = fname
    end

    def log(message)
        File.open(@filename, "a") do |f|
            f.puts("#{Time.now}: #{@name}: #{message}")
        end
    end

end

# We have a central object for creating and retrieving loggers.
# This retains a local reference to all loggers created.  This
# is so an existing logger can be looked up by name, but also
# to prevent loggers from being garbage collected.  A dRuby
# reference to an object is not sufficient to prevent it being
# garbage collected!
class LoggerFactory

    def initialize(bdir)
        @basedir = bdir
        @loggers = {}
    end

    def get_logger(name)
        if !@loggers.has_key? name
            # make the filename safe, then declare it to be so
            fname = name.gsub(/[.\/]/, "_").untaint
            @loggers[name] = Logger.new(name, @basedir + "/" + fname)
        end
        return @loggers[name]
    end

end

FRONT_OBJECT=LoggerFactory.new("/tmp/dlog")

$SAFE = 1   # disable eval() and friends

DRb.start_service(URI, FRONT_OBJECT)
DRb.thread.join

Client code

require 'drb/drb'

SERVER_URI="druby://localhost:8787"

DRb.start_service

log_service=DRbObject.new_with_uri(SERVER_URI)

["loga", "logb", "logc"].each do |logname|

    logger=log_service.get_logger(logname)

    logger.log("Hello, world!")
    logger.log("Goodbye, world!")
    logger.log("=== EOT ===")

end

Security

As with all network services, security needs to be considered when using dRuby. By allowing external access to a Ruby object, you are not only allowing outside clients to call the methods you have defined for that object, but by default to execute arbitrary Ruby code on your server. Consider the following:

# !!! UNSAFE CODE !!!
ro = DRbObject::new_with_uri("druby://your.server.com:8989")
class << ro
  undef :instance_eval  # force call to be passed to remote object
end
ro.instance_eval("`rm -rf *`")

The dangers posed by instance_eval and friends are such that a DRbServer should generally be run with $SAFE set to at least level 1. This will disable eval() and related calls on strings passed across the wire. The sample usage code given above follows this practice.

A DRbServer can be configured with an access control list to selectively allow or deny access from specified IP addresses. The main druby distribution provides the ACL class for this purpose. In general, this mechanism should only be used alongside, rather than as a replacement for, a good firewall.

dRuby internals

dRuby is implemented using three main components: a remote method call marshaller/unmarshaller; a transport protocol; and an ID-to-object mapper. The latter two can be directly, and the first indirectly, replaced, in order to provide different behaviour and capabilities.

Marshalling and unmarshalling of remote method calls is performed by a DRb::DRbMessage instance. This uses the Marshal module to dump the method call before sending it over the transport layer, then reconstitute it at the other end. There is normally no need to replace this component, and no direct way is provided to do so. However, it is possible to implement an alternative marshalling scheme as part of an implementation of the transport layer.

The transport layer is responsible for opening client and server network connections and forwarding dRuby request across them. Normally, it uses DRb::DRbMessage internally to manage marshalling and unmarshalling. The transport layer is managed by DRb::DRbProtocol. Multiple protocols can be installed in DRbProtocol at the one time; selection between them is determined by the scheme of a dRuby URI. The default transport protocol is selected by the scheme 'druby:', and implemented by DRb::DRbTCPSocket. This uses plain TCP/IP sockets for communication. An alternative protocol, using UNIX domain sockets, is implemented by DRb::DRbUNIXSocket in the file drb/unix.rb, and selected by the scheme 'drbunix:'. A sample implementation over HTTP can be found in the samples accompanying the main dRuby distribution.

The ID-to-object mapping component maps dRuby object ids to the objects they refer to, and vice versa. The implementation to use can be specified as part of a DRb::DRbServer's configuration. The default implementation is provided by DRb::DRbIdConv. It uses an object's ObjectSpace id as its dRuby id. This means that the dRuby reference to that object only remains meaningful for the lifetime of the object's process and the lifetime of the object within that process. A modified implementation is provided by DRb::TimerIdConv in the file drb/timeridconv.rb. This implementation retains a local reference to all objects exported over dRuby for a configurable period of time (defaulting to ten minutes), to prevent them being garbage-collected within this time. Another sample implementation is provided in sample/name.rb in the main dRuby distribution. This allows objects to specify their own id or “name”. A dRuby reference can be made persistent across processes by having each process register an object using the same dRuby name.

for ruby-1.8.0

In Files

  • lib/drb/drb.rb
  • lib/drb/eq.rb
  • lib/drb/extserv.rb
  • lib/drb/extservm.rb
  • lib/drb/gw.rb
  • lib/drb/invokemethod.rb
  • lib/drb/observer.rb
  • lib/drb/ssl.rb
  • lib/drb/timeridconv.rb
  • lib/drb/unix.rb

Attributes

primary_server[RW]

The primary local dRuby server.

This is the server created by the start_service call.

Public Class Methods

config() click to toggle source

Get the configuration of the current server.

If there is no current server, this returns the default configuration. See current_server and DRbServer::make_config.

# File lib/drb/drb.rb, line 1727
def config
  current_server.config
rescue
  DRbServer.make_config
end
current_server() click to toggle source

Get the 'current' server.

In the context of execution taking place within the main thread of a dRuby server (typically, as a result of a remote call on the server or one of its objects), the current server is that server. Otherwise, the current server is the primary server.

If the above rule fails to find a server, a DRbServerNotFound error is raised.

# File lib/drb/drb.rb, line 1684
def current_server
  drb = Thread.current['DRb']
  server = (drb && drb['server']) ? drb['server'] : @primary_server
  raise DRbServerNotFound unless server
  return server
end
fetch_server(uri) click to toggle source

Retrieves the server with the given uri.

See also ::regist_server and remove_server.

# File lib/drb/drb.rb, line 1824
def fetch_server(uri)
  @server[uri]
end
front() click to toggle source

Get the front object of the current server.

This raises a DRbServerNotFound error if there is no current server. See current_server.

# File lib/drb/drb.rb, line 1738
def front
  current_server.front
end
here?(uri) click to toggle source

Is uri the URI for the current local server?

# File lib/drb/drb.rb, line 1717
def here?(uri)
  current_server.here?(uri) rescue false
  # (current_server.uri rescue nil) == uri
end
install_acl(acl) click to toggle source

Set the default ACL to acl.

See DRb::DRbServer.default_acl.

# File lib/drb/drb.rb, line 1783
def install_acl(acl)
  DRbServer.default_acl(acl)
end
install_id_conv(idconv) click to toggle source

Set the default id conversion object.

This is expected to be an instance such as DRb::DRbIdConv that responds to to_id and to_obj that can convert objects to and from DRb references.

See DRbServer#default_id_conv.

# File lib/drb/drb.rb, line 1775
def install_id_conv(idconv)
  DRbServer.default_id_conv(idconv)
end
regist_server(server) click to toggle source

Registers server with DRb.

This is called when a new DRb::DRbServer is created.

If there is no primary server then server becomes the primary server.

Example:

require 'drb'

s = DRb::DRbServer.new # automatically calls regist_server
DRb.fetch_server s.uri #=> #<DRb::DRbServer:0x...>

# File lib/drb/drb.rb, line 1807
def regist_server(server)
  @server[server.uri] = server
  mutex.synchronize do
    @primary_server = server unless @primary_server
  end
end
remove_server(server) click to toggle source

Removes server from the list of registered servers.

# File lib/drb/drb.rb, line 1816
def remove_server(server)
  @server.delete(server.uri)
end
start_service(uri=nil, front=nil, config=nil) click to toggle source

Start a dRuby server locally.

The new dRuby server will become the primary server, even if another server is currently the primary server.

uri is the URI for the server to bind to. If nil, the server will bind to random port on the default local host name and use the default dRuby protocol.

front is the server's front object. This may be nil.

config is the configuration for the new server. This may be nil.

See DRb::DRbServer.new.

# File lib/drb/drb.rb, line 1663
def start_service(uri=nil, front=nil, config=nil)
  @primary_server = DRbServer.new(uri, front, config)
end
stop_service() click to toggle source

Stop the local dRuby server.

This operates on the primary server. If there is no primary server currently running, it is a noop.

# File lib/drb/drb.rb, line 1696
def stop_service
  @primary_server.stop_service if @primary_server
  @primary_server = nil
end
thread() click to toggle source

Get the thread of the primary server.

This returns nil if there is no primary server. See primary_server.

# File lib/drb/drb.rb, line 1764
def thread
  @primary_server ? @primary_server.thread : nil
end
to_id(obj) click to toggle source

Get a reference id for an object using the current server.

This raises a DRbServerNotFound error if there is no current server. See current_server.

# File lib/drb/drb.rb, line 1755
def to_id(obj)
  current_server.to_id(obj)
end
to_obj(ref) click to toggle source

Convert a reference into an object using the current server.

This raises a DRbServerNotFound error if there is no current server. See current_server.

# File lib/drb/drb.rb, line 1747
def to_obj(ref)
  current_server.to_obj(ref)
end
uri() click to toggle source

Get the URI defining the local dRuby space.

This is the URI of the current server. See current_server.

# File lib/drb/drb.rb, line 1705
def uri
  drb = Thread.current['DRb']
  client = (drb && drb['client'])
  if client
    uri = client.uri
    return uri if uri
  end
  current_server.uri
end


class DRb::DRbArray - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbArray

An Array wrapper that can be sent to another server via DRb.

All entries in the array will be dumped or be references that point to the local server.

In Files

  • lib/drb/drb.rb

Parent

Object

Public Class Methods

new(ary) click to toggle source

Creates a new DRbArray that either dumps or wraps all the items in the Array ary so they can be loaded by a remote DRb server.

# File lib/drb/drb.rb, line 520
def initialize(ary)
  @ary = ary.collect { |obj|
    if obj.kind_of? DRbUndumped
      DRbObject.new(obj)
    else
      begin
        Marshal.dump(obj)
        obj
      rescue
        DRbObject.new(obj)
      end
    end
  }
end


class DRb::DRbBadScheme - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbBadScheme

Error raised by a dRuby protocol when it doesn't support the scheme specified in a URI. See DRb::DRbProtocol.

In Files

  • lib/drb/drb.rb

Parent

DRb::DRbError


class DRb::DRbBadURI - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbBadURI

Error raised by the DRbProtocol module when it cannot find any protocol implementation support the scheme specified in a URI.

In Files

  • lib/drb/drb.rb

Parent

DRb::DRbError


class DRb::DRbConn - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbConn

Class handling the connection between a DRbObject and the server the real object lives on.

This class maintains a pool of connections, to reduce the overhead of starting and closing down connections for each method call.

This class is used internally by DRbObject. The user does not normally need to deal with it directly.

In Files

  • lib/drb/drb.rb

Parent

Object


class DRb::DRbConnError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbConnError

Error raised when an error occurs on the underlying communication protocol.

In Files

  • lib/drb/drb.rb

Parent

DRb::DRbError


class DRb::DRbError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbError

Superclass of all errors raised in the DRb module.

In Files

  • lib/drb/drb.rb

Parent

RuntimeError


class DRb::DRbIdConv - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbIdConv

Class responsible for converting between an object and its id.

This, the default implementation, uses an object's local ObjectSpace __id__ as its id. This means that an object's identification over drb remains valid only while that object instance remains alive within the server runtime.

For alternative mechanisms, see DRb::TimerIdConv in rdb/timeridconv.rb and DRbNameIdConv in sample/name.rb in the full drb distribution.

In Files

  • lib/drb/drb.rb

Parent

Object

Public Instance Methods

to_id(obj) click to toggle source

Convert an object into a reference id.

This implementation returns the object's __id__ in the local object space.

# File lib/drb/drb.rb, line 376
def to_id(obj)
  obj.nil? ? nil : obj.__id__
end
to_obj(ref) click to toggle source

Convert an object reference id to an object.

This implementation looks up the reference id in the local object space and returns the object it refers to.

# File lib/drb/drb.rb, line 368
def to_obj(ref)
  ObjectSpace._id2ref(ref)
end


class DRb::DRbMessage - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbMessage

Handler for sending and receiving drb messages.

This takes care of the low-level marshalling and unmarshalling of drb requests and responses sent over the wire between server and client. This relieves the implementor of a new drb protocol layer with having to deal with these details.

The user does not have to directly deal with this object in normal use.

In Files

  • lib/drb/drb.rb

Parent

Object


class DRb::DRbObject - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbObject

Object wrapping a reference to a remote drb object.

Method calls on this object are relayed to the remote object that this object is a stub for.

In Files

  • lib/drb/drb.rb
  • lib/drb/eq.rb
  • lib/drb/gw.rb

Parent

Object

Public Class Methods

_load(s) click to toggle source

Unmarshall a marshalled DRbObject.

If the referenced object is located within the local server, then the object itself is returned. Otherwise, a new DRbObject is created to act as a stub for the remote referenced object.

# File lib/drb/drb.rb, line 1021
def self._load(s)
  uri, ref = Marshal.load(s)

  if DRb.here?(uri)
    obj = DRb.to_obj(ref)
    if ((! obj.tainted?) && Thread.current[:drb_untaint])
      Thread.current[:drb_untaint].push(obj)
    end
    return obj
  end

  self.new_with(uri, ref)
end
new(obj, uri=nil) click to toggle source

Create a new remote object stub.

obj is the (local) object we want to create a stub for. Normally this is nil. uri is the URI of the remote object that this will be a stub for.

# File lib/drb/drb.rb, line 1062
def initialize(obj, uri=nil)
  @uri = nil
  @ref = nil
  if obj.nil?
    return if uri.nil?
    @uri, option = DRbProtocol.uri_option(uri, DRb.config)
    @ref = DRbURIOption.new(option) unless option.nil?
  else
    @uri = uri ? uri : (DRb.uri rescue nil)
    @ref = obj ? DRb.to_id(obj) : nil
  end
end
new_with(uri, ref) click to toggle source

Creates a DRb::DRbObject given the reference information to the remote host uri and object ref.

# File lib/drb/drb.rb, line 1038
def self.new_with(uri, ref)
  it = self.allocate
  it.instance_variable_set(:@uri, uri)
  it.instance_variable_set(:@ref, ref)
  it
end
new_with_uri(uri) click to toggle source

Create a new DRbObject from a URI alone.

# File lib/drb/drb.rb, line 1046
def self.new_with_uri(uri)
  self.new(nil, uri)
end

Public Instance Methods

__drbref() click to toggle source

Get the reference of the object, if local.

# File lib/drb/drb.rb, line 1081
def __drbref
  @ref
end
__drburi() click to toggle source

Get the URI of the remote object.

# File lib/drb/drb.rb, line 1076
def __drburi
  @uri
end
_dump(lv) click to toggle source

Marshall this object.

The URI and ref of the object are marshalled.

# File lib/drb/drb.rb, line 1053
def _dump(lv)
  Marshal.dump([@uri, @ref])
end
method_missing(msg_id, *a, &b) click to toggle source

Routes method calls to the referenced remote object.

# File lib/drb/drb.rb, line 1101
def method_missing(msg_id, *a, &b)
  if DRb.here?(@uri)
    obj = DRb.to_obj(@ref)
    DRb.current_server.check_insecure_method(obj, msg_id)
    return obj.__send__(msg_id, *a, &b)
  end

  succ, result = self.class.with_friend(@uri) do
    DRbConn.open(@uri) do |conn|
      conn.send_message(self, msg_id, a, b)
    end
  end

  if succ
    return result
  elsif DRbUnknown === result
    raise result
  else
    bt = self.class.prepare_backtrace(@uri, result)
    result.set_backtrace(bt + caller)
    raise result
  end
end
respond_to?(msg_id, priv=false) click to toggle source

Routes respond_to? to the referenced remote object.

# File lib/drb/drb.rb, line 1089
def respond_to?(msg_id, priv=false)
  case msg_id
  when :_dump
    true
  when :marshal_dump
    false
  else
    method_missing(:respond_to?, msg_id, priv)
  end
end


module DRb::DRbObservable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DRb::DRbObservable

The Observable module extended to DRb. See Observable for details.

In Files

  • lib/drb/observer.rb

Included Modules

  • Observable

Public Instance Methods

notify_observers(*arg) click to toggle source

Notifies observers of a change in state. See also Observable#notify_observers

# File lib/drb/observer.rb, line 10
def notify_observers(*arg)
  if defined? @observer_state and @observer_state
    if defined? @observer_peers
      @observer_peers.each do |observer, method|
        begin
          observer.send(method, *arg)
        rescue
          delete_observer(observer)
        end
      end
    end
    @observer_state = false
  end
end


module DRb::DRbProtocol - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DRb::DRbProtocol

Module managing the underlying network protocol(s) used by drb.

By default, drb uses the DRbTCPSocket protocol. Other protocols can be defined. A protocol must define the following class methods:

[open(uri, config)] Open a client connection to the server at +uri+,
                    using configuration +config+.  Return a protocol
                    instance for this connection.
[open_server(uri, config)] Open a server listening at +uri+,
                           using configuration +config+.  Return a
                           protocol instance for this listener.
[uri_option(uri, config)] Take a URI, possibly containing an option
                          component (e.g. a trailing '?param=val'),
                          and return a [uri, option] tuple.

All of these methods should raise a DRbBadScheme error if the URI does not identify the protocol they support (e.g. “druby:” for the standard Ruby protocol). This is how the DRbProtocol module, given a URI, determines which protocol implementation serves that protocol.

The protocol instance returned by open_server must have the following methods:

accept

Accept a new connection to the server. Returns a protocol instance capable of communicating with the client.

close

Close the server connection.

uri

Get the URI for this server.

The protocol instance returned by open must have the following methods:

send_request (ref, msg_id, arg, b)

Send a request to ref with the given message id and arguments. This is most easily implemented by calling DRbMessage.send_request, providing a stream that sits on top of the current protocol.

recv_reply

Receive a reply from the server and return it as a [success-boolean, reply-value] pair. This is most easily implemented by calling DRb.recv_reply, providing a stream that sits on top of the current protocol.

alive?

Is this connection still alive?

close

Close this connection.

The protocol instance returned by open_server().accept() must have the following methods:

recv_request

Receive a request from the client and return a [object, message, args, block] tuple. This is most easily implemented by calling DRbMessage.recv_request, providing a stream that sits on top of the current protocol.

send_reply(succ, result)

Send a reply to the client. This is most easily implemented by calling DRbMessage.send_reply, providing a stream that sits on top of the current protocol.

close

Close this connection.

A new protocol is registered with the DRbProtocol module using the ::add_protocol method.

For examples of other protocols, see DRbUNIXSocket in drb/unix.rb, and HTTP0 in sample/http0.rb and sample/http0serv.rb in the full drb distribution.

In Files

  • lib/drb/drb.rb

Public Class Methods

add_protocol(prot) click to toggle source

Add a new protocol to the DRbProtocol module.

# File lib/drb/drb.rb, line 721
def add_protocol(prot)
  @protocol.push(prot)
end
open(uri, config, first=true) click to toggle source

Open a client connection to uri with the configuration config.

The DRbProtocol module asks each registered protocol in turn to try to open the URI. Each protocol signals that it does not handle that URI by raising a DRbBadScheme error. If no protocol recognises the URI, then a DRbBadURI error is raised. If a protocol accepts the URI, but an error occurs in opening it, a DRbConnError is raised.

# File lib/drb/drb.rb, line 733
def open(uri, config, first=true)
  @protocol.each do |prot|
    begin
      return prot.open(uri, config)
    rescue DRbBadScheme
    rescue DRbConnError
      raise($!)
    rescue
      raise(DRbConnError, "#{uri} - #{$!.inspect}")
    end
  end
  if first && (config[:auto_load] != false)
    auto_load(uri, config)
    return open(uri, config, false)
  end
  raise DRbBadURI, 'can\t parse uri:' + uri
end
open_server(uri, config, first=true) click to toggle source

Open a server listening for connections at uri with configuration config.

The DRbProtocol module asks each registered protocol in turn to try to open a server at the URI. Each protocol signals that it does not handle that URI by raising a DRbBadScheme error. If no protocol recognises the URI, then a DRbBadURI error is raised. If a protocol accepts the URI, but an error occurs in opening it, the underlying error is passed on to the caller.

# File lib/drb/drb.rb, line 761
def open_server(uri, config, first=true)
  @protocol.each do |prot|
    begin
      return prot.open_server(uri, config)
    rescue DRbBadScheme
    end
  end
  if first && (config[:auto_load] != false)
    auto_load(uri, config)
    return open_server(uri, config, false)
  end
  raise DRbBadURI, 'can\t parse uri:' + uri
end
uri_option(uri, config, first=true) click to toggle source

Parse uri into a [uri, option] pair.

The DRbProtocol module asks each registered protocol in turn to try to parse the URI. Each protocol signals that it does not handle that URI by raising a DRbBadScheme error. If no protocol recognises the URI, then a DRbBadURI error is raised.

# File lib/drb/drb.rb, line 782
def uri_option(uri, config, first=true)
  @protocol.each do |prot|
    begin
      uri, opt = prot.uri_option(uri, config)
      # opt = nil if opt == ''
      return uri, opt
    rescue DRbBadScheme
    end
  end
  if first && (config[:auto_load] != false)
    auto_load(uri, config)
    return uri_option(uri, config, false)
  end
  raise DRbBadURI, 'can\t parse uri:' + uri
end


class DRb::DRbRemoteError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbRemoteError

An exception wrapping an error object

In Files

  • lib/drb/drb.rb

Parent

DRb::DRbError

Attributes

reason[R]

the class of the error, as a string.

Public Class Methods

new(error) click to toggle source

Creates a new remote error that wraps the Exception error

# File lib/drb/drb.rb, line 431
def initialize(error)
  @reason = error.class.to_s
  super("#{error.message} (#{error.class})")
  set_backtrace(error.backtrace)
end


class DRb::DRbSSLSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbSSLSocket

The protocol for DRb over an SSL socket

The URI for a DRb socket over SSL is: drbssl://<host>:<port>?<option>. The option is optional

In Files

  • lib/drb/ssl.rb

Parent

DRb::DRbTCPSocket

Public Class Methods

new(uri, soc, config, is_established) click to toggle source

Create a DRb::DRbSSLSocket instance.

uri is the URI we are connected to. soc is the tcp socket we are bound to. config is our configuration. Either a Hash or SSLConfig is_established is a boolean of whether soc is currenly established

This is called automatically based on the DRb protocol.

# File lib/drb/ssl.rb, line 305
def initialize(uri, soc, config, is_established)
  @ssl = is_established ? soc : nil
  super(uri, soc.to_io, config)
end
open(uri, config) click to toggle source

Return an DRb::DRbSSLSocket instance as a client-side connection, with the SSL connected. This is called from DRb.start_service or while connecting to a remote object:

DRb.start_service 'drbssl://localhost:0', front, config

uri is the URI we are connected to, 'drbssl://localhost:0' above, config is our configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig

# File lib/drb/ssl.rb, line 248
def self.open(uri, config)
  host, port, = parse_uri(uri)
  host.untaint
  port.untaint
  soc = TCPSocket.open(host, port)
  ssl_conf = SSLConfig::new(config)
  ssl_conf.setup_ssl_context
  ssl = ssl_conf.connect(soc)
  self.new(uri, ssl, ssl_conf, true)
end
open_server(uri, config) click to toggle source

Returns a DRb::DRbSSLSocket instance as a server-side connection, with the SSL connected. This is called from DRb.start_service or while connecting to a remote object:

DRb.start_service 'drbssl://localhost:0', front, config

uri is the URI we are connected to, 'drbssl://localhost:0' above, config is our configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig

# File lib/drb/ssl.rb, line 268
def self.open_server(uri, config)
  uri = 'drbssl://:0' unless uri
  host, port, = parse_uri(uri)
  if host.size == 0
    host = getservername
    soc = open_server_inaddr_any(host, port)
  else
    soc = TCPServer.open(host, port)
  end
  port = soc.addr[1] if port == 0
  @uri = "drbssl://#{host}:#{port}"

  ssl_conf = SSLConfig.new(config)
  ssl_conf.setup_certificate
  ssl_conf.setup_ssl_context
  self.new(@uri, soc, ssl_conf, false)
end

Public Instance Methods

stream() click to toggle source

Returns the SSL stream

# File lib/drb/ssl.rb, line 311
def stream; @ssl; end


class DRb::DRbSSLSocket::SSLConfig - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbSSLSocket::SSLConfig

SSLConfig handles the needed SSL information for establishing a DRbSSLSocket connection, including generating the X509 / RSA pair.

An instance of this config can be passed to DRb::DRbSSLSocket.new, DRb::DRbSSLSocket.open and DRb::DRbSSLSocket.open_server

See ::new for more details

In Files

  • lib/drb/ssl.rb

Parent

Object

Constants

DEFAULT

Default values for a SSLConfig instance.

See ::new for more details

Public Class Methods

new(config) click to toggle source

Create a new DRb::DRbSSLSocket::SSLConfig instance

The DRb::DRbSSLSocket will take either a config Hash or an instance of SSLConfg, and will setup the certificate for its session for the configuration. If want it to generate a generic certificate, the bare minimum is to provide the :SSLCertName

Config options

From config Hash:

:SSLCertificate

An instance of OpenSSL::X509::Certificate. If this is not provided, then a generic X509 is generated, with a correspond :SSLPrivateKey

:SSLPrivateKey

A private key instance, like OpenSSL::PKey::RSA. This key must be the key that signed the :SSLCertificate

:SSLClientCA

An OpenSSL::X509::Certificate, or Array of certificates that will used as ClientCAs in the SSL Context

:SSLCACertificatePath

A path to the directory of CA certificates. The certificates must be in PEM format.

:SSLCACertificateFile

A path to a CA certificate file, in PEM format.

:SSLTmpDhCallback

A DH callback. See OpenSSL::SSL::SSLContext#tmp_dh_callback

:SSLVerifyMode

This is the SSL verification mode. See OpenSSL::SSL::VERIFY_* for available modes. The default is OpenSSL::SSL::VERIFY_NONE

:SSLVerifyDepth

Number of CA certificates to walk, when verifying a certificate chain.

:SSLVerifyCallback

A callback to be used for additional verification. See OpenSSL::SSL::SSLContext#verify_callback

:SSLCertificateStore

A OpenSSL::X509::Store used for verification of certificates

:SSLCertName

Issuer name for the certificate. This is required when generating the certificate (if :SSLCertificate and :SSLPrivateKey were not given). The value of this is to be an Array of pairs:

[["C", "Raleigh"], ["ST","North Carolina"],
 ["CN","fqdn.example.com"]]

See also OpenSSL::X509::Name

:SSLCertComment

A comment to be used for generating the certificate. The default is “Generated by Ruby/OpenSSL”

Example

These values can be added after the fact, like a Hash.

require 'drb/ssl'
c = DRb::DRbSSLSocket::SSLConfig.new {}
c[:SSLCertificate] =
  OpenSSL::X509::Certificate.new(File.read('mycert.crt'))
c[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(File.read('mycert.key'))
c[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
c[:SSLCACertificatePath] = "/etc/ssl/certs/"
c.setup_certificate

or

require 'drb/ssl'
c = DRb::DRbSSLSocket::SSLConfig.new({
        :SSLCertName => [["CN" => DRb::DRbSSLSocket.getservername]]
        })
c.setup_certificate

# File lib/drb/ssl.rb, line 126
def initialize(config)
  @config  = config
  @cert    = config[:SSLCertificate]
  @pkey    = config[:SSLPrivateKey]
  @ssl_ctx = nil
end

Public Instance Methods

[](key) click to toggle source

A convenience method to access the values like a Hash

# File lib/drb/ssl.rb, line 134
def [](key);
  @config[key] || DEFAULT[key]
end
accept(tcp) click to toggle source

Accept connection to IO tcp, with context of the current certificate configuration

# File lib/drb/ssl.rb, line 149
def accept(tcp)
  ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
  ssl.sync = true
  ssl.accept
  ssl
end
connect(tcp) click to toggle source

Connect to IO tcp, with context of the current certificate configuration

# File lib/drb/ssl.rb, line 140
def connect(tcp)
  ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
  ssl.sync = true
  ssl.connect
  ssl
end
setup_certificate() click to toggle source

Ensures that :SSLCertificate and :SSLPrivateKey have been provided or that a new certificate is generated with the other parameters provided.

# File lib/drb/ssl.rb, line 159
def setup_certificate
  if @cert && @pkey
    return
  end

  rsa = OpenSSL::PKey::RSA.new(1024){|p, n|
    next unless self[:verbose]
    case p
    when 0; $stderr.putc "."  # BN_generate_prime
    when 1; $stderr.putc "+"  # BN_generate_prime
    when 2; $stderr.putc "*"  # searching good prime,
                              # n = #of try,
                              # but also data from BN_generate_prime
    when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
                              # but also data from BN_generate_prime
    else;   $stderr.putc "*"  # BN_generate_prime
    end
  }

  cert = OpenSSL::X509::Certificate.new
  cert.version = 3
  cert.serial = 0
  name = OpenSSL::X509::Name.new(self[:SSLCertName])
  cert.subject = name
  cert.issuer = name
  cert.not_before = Time.now
  cert.not_after = Time.now + (365*24*60*60)
  cert.public_key = rsa.public_key

  ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
  cert.extensions = [
    ef.create_extension("basicConstraints","CA:FALSE"),
    ef.create_extension("subjectKeyIdentifier", "hash") ]
  ef.issuer_certificate = cert
  cert.add_extension(ef.create_extension("authorityKeyIdentifier",
                                         "keyid:always,issuer:always"))
  if comment = self[:SSLCertComment]
    cert.add_extension(ef.create_extension("nsComment", comment))
  end
  cert.sign(rsa, OpenSSL::Digest::SHA1.new)

  @cert = cert
  @pkey = rsa
end
setup_ssl_context() click to toggle source

Establish the OpenSSL::SSL::SSLContext with the configuration parameters provided.

# File lib/drb/ssl.rb, line 206
def setup_ssl_context
  ctx = ::OpenSSL::SSL::SSLContext.new
  ctx.cert            = @cert
  ctx.key             = @pkey
  ctx.client_ca       = self[:SSLClientCA]
  ctx.ca_path         = self[:SSLCACertificatePath]
  ctx.ca_file         = self[:SSLCACertificateFile]
  ctx.tmp_dh_callback = self[:SSLTmpDhCallback]
  ctx.verify_mode     = self[:SSLVerifyMode]
  ctx.verify_depth    = self[:SSLVerifyDepth]
  ctx.verify_callback = self[:SSLVerifyCallback]
  ctx.cert_store      = self[:SSLCertificateStore]
  @ssl_ctx = ctx
end


class DRb::DRbServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbServer

Class representing a drb server instance.

A DRbServer must be running in the local process before any incoming dRuby calls can be accepted, or any local objects can be passed as dRuby references to remote processes, even if those local objects are never actually called remotely. You do not need to start a DRbServer in the local process if you are only making outgoing dRuby calls passing marshalled parameters.

Unless multiple servers are being used, the local DRbServer is normally started by calling DRb.start_service.

In Files

  • lib/drb/drb.rb
  • lib/drb/invokemethod.rb

Parent

Object

Constants

INSECURE_METHOD

List of insecure methods.

These methods are not callable via dRuby.

Attributes

config[R]

The configuration of this DRbServer

front[R]

The front object of the DRbServer.

This object receives remote method calls made on the server's URI alone, with an object id.

safe_level[R]

The safe level for this server. This is a number corresponding to $SAFE.

The default #safe_level is 0

thread[R]

The main thread of this DRbServer.

This is the thread that listens for and accepts connections from clients, not that handles each client's request-response session.

uri[R]

The URI of this DRbServer.

Public Class Methods

default_acl(acl) click to toggle source

Set the default access control list to acl. The default ACL is nil.

See also DRb::ACL and new()

# File lib/drb/drb.rb, line 1273
def self.default_acl(acl)
  @@acl = acl
end
default_argc_limit(argc) click to toggle source

Set the default value for the :argc_limit option.

See new(). The initial default value is 256.

# File lib/drb/drb.rb, line 1259
def self.default_argc_limit(argc)
  @@argc_limit = argc
end
default_id_conv(idconv) click to toggle source

Set the default value for the :id_conv option.

See new(). The initial default value is a DRbIdConv instance.

# File lib/drb/drb.rb, line 1280
def self.default_id_conv(idconv)
  @@idconv = idconv
end
default_load_limit(sz) click to toggle source

Set the default value for the :load_limit option.

See new(). The initial default value is 25 MB.

# File lib/drb/drb.rb, line 1266
def self.default_load_limit(sz)
  @@load_limit = sz
end
default_safe_level(level) click to toggle source

Set the default safe level to level. The default safe level is 0

See new for more information.

# File lib/drb/drb.rb, line 1287
def self.default_safe_level(level)
  @@safe_level = level
end
new(uri=nil, front=nil, config_or_acl=nil) click to toggle source

Create a new DRbServer instance.

uri is the URI to bind to. This is normally of the form 'druby://<hostname>:<port>' where <hostname> is a hostname of the local machine. If nil, then the system's default hostname will be bound to, on a port selected by the system; these value can be retrieved from the uri attribute. 'druby:' specifies the default dRuby transport protocol: another protocol, such as 'drbunix:', can be specified instead.

front is the front object for the server, that is, the object to which remote method calls on the server will be passed. If nil, then the server will not accept remote method calls.

If config_or_acl is a hash, it is the configuration to use for this server. The following options are recognised:

:idconv

an id-to-object conversion object. This defaults to an instance of the class DRb::DRbIdConv.

:verbose

if true, all unsuccessful remote calls on objects in the server will be logged to $stdout. false by default.

:tcp_acl

the access control list for this server. See the ACL class from the main dRuby distribution.

:load_limit

the maximum message size in bytes accepted by the server. Defaults to 25 MB (26214400).

:argc_limit

the maximum number of arguments to a remote method accepted by the server. Defaults to 256.

:#safe_level

The safe level of the DRbServer. The attribute sets $SAFE for methods performed in the main_loop. Defaults to 0.

The default values of these options can be modified on a class-wide basis by the class methods default_argc_limit, default_load_limit, default_acl, default_id_conv, and verbose=

If config_or_acl is not a hash, but is not nil, it is assumed to be the access control list for this server. See the :tcp_acl option for more details.

If no other server is currently set as the primary server, this will become the primary server.

The server will immediately start running in its own thread.

# File lib/drb/drb.rb, line 1361
def initialize(uri=nil, front=nil, config_or_acl=nil)
  if Hash === config_or_acl
    config = config_or_acl.dup
  else
    acl = config_or_acl || @@acl
    config = {
      :tcp_acl => acl
    }
  end

  @config = self.class.make_config(config)

  @protocol = DRbProtocol.open_server(uri, @config)
  @uri = @protocol.uri
  @exported_uri = [@uri]

  @front = front
  @idconv = @config[:idconv]
  @safe_level = @config[:safe_level]

  @grp = ThreadGroup.new
  @thread = run

  DRb.regist_server(self)
end
verbose() click to toggle source

Get the default value of the :verbose option.

# File lib/drb/drb.rb, line 1299
def self.verbose
  @@verbose
end
verbose=(on) click to toggle source

Set the default value of the :verbose option.

See new(). The initial default value is false.

# File lib/drb/drb.rb, line 1294
def self.verbose=(on)
  @@verbose = on
end

Public Instance Methods

alive?() click to toggle source

Is this server alive?

# File lib/drb/drb.rb, line 1423
def alive?
  @thread.alive?
end
check_insecure_method(obj, msg_id) click to toggle source

Check that a method is callable via dRuby.

obj is the object we want to invoke the method on. msg_id is the method name, as a Symbol.

If the method is an insecure method (see insecure_method?) a SecurityError is thrown. If the method is private or undefined, a NameError is thrown.

# File lib/drb/drb.rb, line 1500
def check_insecure_method(obj, msg_id)
  return true if Proc === obj && msg_id == :__drb_yield
  raise(ArgumentError, "#{any_to_s(msg_id)} is not a symbol") unless Symbol == msg_id.class
  raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(msg_id)

  if obj.private_methods.include?(msg_id)
    desc = any_to_s(obj)
    raise NoMethodError, "private method `#{msg_id}' called for #{desc}"
  elsif obj.protected_methods.include?(msg_id)
    desc = any_to_s(obj)
    raise NoMethodError, "protected method `#{msg_id}' called for #{desc}"
  else
    true
  end
end
here?(uri) click to toggle source

Is uri the URI for this server?

# File lib/drb/drb.rb, line 1428
def here?(uri)
  @exported_uri.include?(uri)
end
stop_service() click to toggle source

Stop this server.

# File lib/drb/drb.rb, line 1433
def stop_service
  DRb.remove_server(self)
  if  Thread.current['DRb'] && Thread.current['DRb']['server'] == self
    Thread.current['DRb']['stop_service'] = true
  else
    @thread.kill.join
  end
end
to_id(obj) click to toggle source

Convert a local object to a dRuby reference.

# File lib/drb/drb.rb, line 1450
def to_id(obj)
  return nil if obj.__id__ == front.__id__
  @idconv.to_id(obj)
end
to_obj(ref) click to toggle source

Convert a dRuby reference to the local object it refers to.

# File lib/drb/drb.rb, line 1443
def to_obj(ref)
  return front if ref.nil?
  return front[ref.to_s] if DRbURIOption === ref
  @idconv.to_obj(ref)
end
verbose() click to toggle source

Get whether the server is in verbose mode.

In verbose mode, failed calls are logged to stdout.

# File lib/drb/drb.rb, line 1420
def verbose; @config[:verbose]; end
verbose=(v) click to toggle source

Set whether to operate in verbose mode.

In verbose mode, failed calls are logged to stdout.

# File lib/drb/drb.rb, line 1415
def verbose=(v); @config[:verbose]=v; end


class DRb::DRbServerNotFound - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbServerNotFound

Error raised by the DRb module when an attempt is made to refer to the context's current drb server but the context does not have one. See current_server.

In Files

  • lib/drb/drb.rb

Parent

DRb::DRbError


class DRb::DRbTCPSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbTCPSocket

The default drb protocol which communicates over a TCP socket.

The DRb TCP protocol URI looks like: druby://<host>:<port>?<option>. The option is optional.

In Files

  • lib/drb/drb.rb

Parent

Object


class DRb::DRbUNIXSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbUNIXSocket

Implements DRb over a UNIX socket

DRb UNIX socket URIs look like drbunix:<path>?<option>. The option is optional.

In Files

  • lib/drb/unix.rb

Parent

DRb::DRbTCPSocket


module DRb::DRbUndumped - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module DRb::DRbUndumped

Mixin module making an object undumpable or unmarshallable.

If an object which includes this module is returned by method called over drb, then the object remains in the server space and a reference to the object is returned, rather than the object being marshalled and moved into the client space.

In Files

  • lib/drb/drb.rb


class DRb::DRbUnknown - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbUnknown

Class wrapping a marshalled object whose type is unknown locally.

If an object is returned by a method invoked over drb, but the class of the object is unknown in the client namespace, or the object is a constant unknown in the client namespace, then the still-marshalled object is returned wrapped in a DRbUnknown instance.

If this object is passed as an argument to a method invoked over drb, then the wrapped object is passed instead.

The class or constant name of the object can be read from the name attribute. The marshalled object is held in the buf attribute.

In Files

  • lib/drb/drb.rb

Parent

Object

Attributes

buf[R]

Buffer contained the marshalled, unknown object.

name[R]

The name of the unknown thing.

Class name for unknown objects; variable name for unknown constants.

Public Class Methods

new(err, buf) click to toggle source

Create a new DRbUnknown object.

buf is a string containing a marshalled object that could not be unmarshalled. err is the error message that was raised when the unmarshalling failed. It is used to determine the name of the unmarshalled object.

# File lib/drb/drb.rb, line 462
def initialize(err, buf)
  case err.to_s
  when /uninitialized constant (\S+)/
    @name = $1
  when /undefined class\/module (\S+)/
    @name = $1
  else
    @name = nil
  end
  @buf = buf
end

Public Instance Methods

exception() click to toggle source

Create a DRbUnknownError exception containing this object.

# File lib/drb/drb.rb, line 505
def exception
  DRbUnknownError.new(self)
end
reload() click to toggle source

Attempt to load the wrapped marshalled object again.

If the class of the object is now known locally, the object will be unmarshalled and returned. Otherwise, a new but identical DRbUnknown object will be returned.

# File lib/drb/drb.rb, line 500
def reload
  self.class._load(@buf)
end


class DRb::DRbUnknownError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::DRbUnknownError

An exception wrapping a DRb::DRbUnknown object

In Files

  • lib/drb/drb.rb

Parent

DRb::DRbError

Attributes

unknown[R]

Get the wrapped DRb::DRbUnknown object.

Public Class Methods

new(unknown) click to toggle source

Create a new DRbUnknownError for the DRb::DRbUnknown object unknown

# File lib/drb/drb.rb, line 410
def initialize(unknown)
  @unknown = unknown
  super(unknown.name)
end


class DRb::ExtServ - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::ExtServ

In Files

  • lib/drb/extserv.rb

Parent

Object

Included Modules

  • MonitorMixin
  • DRb::DRbUndumped

Attributes

server[R]

Public Class Methods

new(there, name, server=nil) click to toggle source
# File lib/drb/extserv.rb, line 14
def initialize(there, name, server=nil)
  super()
  @server = server || DRb::primary_server
  @name = name
  ro = DRbObject.new(nil, there)
  synchronize do
    @invoker = ro.regist(name, DRbObject.new(self, @server.uri))
  end
end

Public Instance Methods

alive?() click to toggle source
# File lib/drb/extserv.rb, line 39
def alive?
  @server ? @server.alive? : false
end
front() click to toggle source
# File lib/drb/extserv.rb, line 25
def front
  DRbObject.new(nil, @server.uri)
end
stop_service() click to toggle source
# File lib/drb/extserv.rb, line 29
def stop_service
  synchronize do
    @invoker.unregist(@name)
    server = @server
    @server = nil
    server.stop_service
    true
  end
end


class DRb::ExtServManager - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::ExtServManager

In Files

  • lib/drb/extservm.rb

Parent

Object

Included Modules

  • DRb::DRbUndumped
  • MonitorMixin

Attributes

uri[RW]

Public Class Methods

command() click to toggle source
# File lib/drb/extservm.rb, line 17
def self.command
  @@command
end
command=(cmd) click to toggle source
# File lib/drb/extservm.rb, line 21
def self.command=(cmd)
  @@command = cmd
end
new() click to toggle source
# File lib/drb/extservm.rb, line 25
def initialize
  super()
  @cond = new_cond
  @servers = {}
  @waiting = []
  @queue = Queue.new
  @thread = invoke_thread
  @uri = nil
end

Public Instance Methods

regist(name, ro) click to toggle source
# File lib/drb/extservm.rb, line 47
def regist(name, ro)
  synchronize do
    @servers[name] = ro
    @cond.signal
  end
  self
end
service(name) click to toggle source
# File lib/drb/extservm.rb, line 36
def service(name)
  synchronize do
    while true
      server = @servers[name]
      return server if server && server.alive?
      invoke_service(name)
      @cond.wait
    end
  end
end
unregist(name) click to toggle source
# File lib/drb/extservm.rb, line 55
def unregist(name)
  synchronize do
    @servers.delete(name)
  end
end


class DRb::GW - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::GW

The GW provides a synchronized store for participants in the gateway to communicate.

In Files

  • lib/drb/gw.rb

Parent

Object

Included Modules

  • MonitorMixin

Public Class Methods

new() click to toggle source

Creates a new GW

# File lib/drb/gw.rb, line 50
def initialize
  super()
  @hash = {}
end

Public Instance Methods

[](key) click to toggle source

Retrieves key from the GW

# File lib/drb/gw.rb, line 57
def [](key)
  synchronize do
    @hash[key]
  end
end
[]=(key, v) click to toggle source

Stores value v at key in the GW

# File lib/drb/gw.rb, line 65
def []=(key, v)
  synchronize do
    @hash[key] = v
  end
end


class DRb::GWIdConv - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::GWIdConv

Gateway id conversion forms a gateway between different DRb protocols or networks.

The gateway needs to install this id conversion and create servers for each of the protocols or networks it will be a gateway between. It then needs to create a server that attaches to each of these networks. For example:

require 'drb/drb'
require 'drb/unix'
require 'drb/gw'

DRb.install_id_conv DRb::GWIdConv.new
gw = DRb::GW.new
s1 = DRb::DRbServer.new 'drbunix:/path/to/gateway', gw
s2 = DRb::DRbServer.new 'druby://example:10000', gw

s1.thread.join
s2.thread.join

Each client must register services with the gateway, for example:

DRb.start_service 'drbunix:', nil # an anonymous server
gw = DRbObject.new nil, 'drbunix:/path/to/gateway'
gw[:unix] = some_service
DRb.thread.join

In Files

  • lib/drb/gw.rb

Parent

DRb::DRbIdConv


class DRb::TimerIdConv - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::TimerIdConv

Timer id conversion keeps objects alive for a certain amount of time after their last access. The default time period is 600 seconds and can be changed upon initialization.

To use TimerIdConv:

DRb.install_id_conv TimerIdConv.new 60 # one minute

In Files

  • lib/drb/timeridconv.rb

Parent

DRb::DRbIdConv

Public Class Methods

new(timeout=600) click to toggle source

Creates a new TimerIdConv which will hold objects for timeout seconds.

# File lib/drb/timeridconv.rb, line 84
def initialize(timeout=600)
  @holder = TimerHolder2.new(timeout)
end


class DRb::TimerIdConv::TimerHolder2 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::TimerIdConv::TimerHolder2

In Files

  • lib/drb/timeridconv.rb

Parent

Object


class DRb::TimerIdConv::TimerHolder2::InvalidIndexError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DRb::TimerIdConv::TimerHolder2::InvalidIndexError

In Files

  • lib/drb/timeridconv.rb

Parent

RuntimeError


class Date - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Date

date and datetime class - Tadayoshi Funaba 1998-2011

'date' provides two classes Date and DateTime.

Terms and definitions

Some terms and definitions are based on ISO 8601 and JIS X 0301.

calendar date

The calendar date is a particular day of a calendar year, identified by its ordinal number within a calendar month within that year.

In those classes, this is so-called “civil”.

ordinal date

The ordinal date is a particular day of a calendar year identified by its ordinal number within the year.

In those classes, this is so-called “ordinal”.

week date

The week date is a date identified by calendar week and day numbers.

The calendar week is a seven day period within a calendar year, starting on a Monday and identified by its ordinal number within the year; the first calendar week of the year is the one that includes the first Thursday of that year. In the Gregorian calendar, this is equivalent to the week which includes January 4.

In those classes, this so-called “commercial”.

julian day number

The Julian day number is in elapsed days since noon (Greenwich mean time) on January 1, 4713 BCE (in the Julian calendar).

In this document, the astronomical Julian day number is same as the original Julian day number. And the chronological Julian day number is a variation of the Julian day number. Its days begin at midnight on local time.

In this document, when the term “Julian day number” simply appears, it just refers to “chronological Julian day number”, not the original.

In those classes, those are so-called “ajd” and “jd”.

modified julian day number

The modified Julian day number is in elapsed days since midnight (Coordinated universal time) on November 17, 1858 CE (in the Gregorian calendar).

In this document, the astronomical modified Julian day number is same as the original modified Julian day number. And the chronological modified Julian day number is a variation of the modified Julian day number. Its days begin at midnight on local time.

In this document, when the term “modified Julian day number” simply appears, it just refers to “chronological modified Julian day number”, not the original.

In those classes, this is so-called “mjd”.

Date

A subclass of Object includes Comparable module, easily handles date.

Date object is created with ::new, ::jd, ::ordinal, ::commercial, ::parse, ::strptime, ::today, Time#to_date or etc.

require 'date'

Date.new(2001,2,3)           #=> #<Date: 2001-02-03 ...>
Date.jd(2451944)             #=> #<Date: 2001-02-03 ...>
Date.ordinal(2001,34)        #=> #<Date: 2001-02-03 ...>
Date.commercial(2001,5,6)    #=> #<Date: 2001-02-03 ...>
Date.parse('2001-02-03')     #=> #<Date: 2001-02-03 ...>
Date.strptime('03-02-2001', '%d-%m-%Y')
                             #=> #<Date: 2001-02-03 ...>
Time.new(2001,2,3).to_date   #=> #<Date: 2001-02-03 ...>

All date objects are immutable; hence cannot modify themselves.

The concept of this date object can be represented as a tuple of the day count, the offset and the day of calendar reform.

The day count denotes the absolute position of a temporal dimension. The offset is relative adjustment, which determines decoded local time with the day count. The day of calendar reform denotes the start day of the new style. The old style of the West is the Julian calendar which was adopted by Caersar. The new style is the Gregorian calendar, which is the current civil calendar of many countries.

The day count is virtually the astronomical Julian day number. The offset in this class is usually zero, and cannot be specified directly.

An optional argument the day of calendar reform (start) as a Julian day number, which should be 2298874 to 2426355 or -/+oo. The default value is Date::ITALY (2299161=1582-10-15). See also sample/cal.rb.

$ ruby sample/cal.rb -c it 10 1582
    October 1582
 S  M Tu  W Th  F  S
    1  2  3  4 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

$ ruby sample/cal.rb -c gb  9 1752
   September 1752
 S  M Tu  W Th  F  S
       1  2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Date object has various methods. See each reference.

d = Date.parse('3rd Feb 2001')
                             #=> #<Date: 2001-02-03 ...>
d.year                       #=> 2001
d.mon                        #=> 2
d.mday                       #=> 3
d.wday                       #=> 6
d += 1                       #=> #<Date: 2001-02-04 ...>
d.strftime('%a %d %b %Y')    #=> "Sun 04 Feb 2001"

DateTime

A subclass of Date easily handles date, hour, minute, second and offset.

DateTime does not consider any leapseconds, does not track any summer time rules.

DateTime object is created with DateTime.new, DateTime.jd, DateTime.ordinal, DateTime.commercial, DateTime.parse, DateTime.strptime, DateTime.now, Time#to_datetime or etc.

require 'date'

DateTime.new(2001,2,3,4,5,6)
                     #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>

The last element of day, hour, minute or senond can be fractional number. The fractional number's precision is assumed at most nanosecond.

DateTime.new(2001,2,3.5)
                     #=> #<DateTime: 2001-02-03T12:00:00+00:00 ...>

An optional argument the offset indicates the difference between the local time and UTC. For example, Rational(3,24) represents ahead of 3 hours of UTC, Rational(-5,24) represents behind of 5 hours of UTC. The offset should be -1 to +1, and its precision is assumed at most second. The default value is zero (equals to UTC).

DateTime.new(2001,2,3,4,5,6,Rational(3,24))
                     #=> #<DateTime: 2001-02-03T04:05:06+03:00 ...>

also accepts string form.

DateTime.new(2001,2,3,4,5,6,'+03:00')
                     #=> #<DateTime: 2001-02-03T04:05:06+03:00 ...>

An optional argument the day of calendar reform (start) denotes a Julian day number, which should be 2298874 to 2426355 or -/+oo. The default value is Date::ITALY (2299161=1582-10-15).

DateTime object has various methods. See each reference.

d = DateTime.parse('3rd Feb 2001 04:05:06+03:30')
                     #=> #<DateTime: 2001-02-03T04:05:06+03:30 ...>
d.hour               #=> 4
d.min                #=> 5
d.sec                #=> 6
d.offset             #=> (7/48)
d.zone               #=> "+03:30"
d += Rational('1.5')
                     #=> #<DateTime: 2001-02-04%16:05:06+03:30 ...>
d = d.new_offset('+09:00')
                     #=> #<DateTime: 2001-02-04%21:35:06+09:00 ...>
d.strftime('%I:%M:%S %p')
                     #=> "09:35:06 PM"
d > DateTime.new(1999)
                     #=> true

Date serialization/deserialization

In Files

  • lib/rubygems/specification.rb
  • ext/date/date_core.c
  • ext/json/lib/json/add/date.rb

Parent

Object

Included Modules

  • Comparable

Constants

ABBR_DAYNAMES

An array of string of abbreviated day name in English. The first is “Sun”.

ABBR_MONTHNAMES

An array of string of abbreviated month name in English. The first element is nil.

DAYNAMES

An array of string of full name of days of the week in English. The first is “Sunday”.

ENGLAND

The Julian day number of the day of calendar reform for England and her colonies.

GREGORIAN

The Julian day number of the day of calendar reform for the proleptic Gregorian calendar

ITALY

The Julian day number of the day of calendar reform for Italy and some catholic countries.

JULIAN

The Julian day number of the day of calendar reform for the proleptic Julian calendar

MONTHNAMES

An array of stirng of full month name in English. The first element is nil.

Public Class Methods

_httpdate(string) → hash click to toggle source

Returns a hash of parsed elements.

static VALUE
date_s__httpdate(VALUE klass, VALUE str)
{
    return date__httpdate(str);
}
_iso8601(string) → hash click to toggle source

Returns a hash of parsed elements.

static VALUE
date_s__iso8601(VALUE klass, VALUE str)
{
    return date__iso8601(str);
}
_jisx0301(string) → hash click to toggle source

Returns a hash of parsed elements.

static VALUE
date_s__jisx0301(VALUE klass, VALUE str)
{
    return date__jisx0301(str);
}
_parse(string[, comp=true]) → hash click to toggle source

Parses the given representation of date and time, and returns a hash of parsed elements. This method does not function as a validator.

If the optional second argument is true and the detected year is in the range “00” to “99”, considers the year a 2-digit form and makes it full.

Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3}

static VALUE
date_s__parse(int argc, VALUE *argv, VALUE klass)
{
    return date_s__parse_internal(argc, argv, klass);
}
_rfc2822(string) → hash click to toggle source
_rfc822(string) → hash

Returns a hash of parsed elements.

static VALUE
date_s__rfc2822(VALUE klass, VALUE str)
{
    return date__rfc2822(str);
}
_rfc3339(string) → hash click to toggle source

Returns a hash of parsed elements.

static VALUE
date_s__rfc3339(VALUE klass, VALUE str)
{
    return date__rfc3339(str);
}
_rfc2822(string) → hash click to toggle source
_rfc822(string) → hash

Returns a hash of parsed elements.

static VALUE
date_s__rfc2822(VALUE klass, VALUE str)
{
    return date__rfc2822(str);
}
_strptime(string[, format='%F']) → hash click to toggle source

Parses the given representation of date and time with the given template, and returns a hash of parsed elements. _strptime does not support specification of flags and width unlike strftime.

  Date._strptime('2001-02-03', '%Y-%m-%d')
                            #=> {:year=>2001, :mon=>2, :mday=>3}

See also strptime(3) and strftime.

static VALUE
date_s__strptime(int argc, VALUE *argv, VALUE klass)
{
    return date_s__strptime_internal(argc, argv, klass, "%F");
}
_xmlschema(string) → hash click to toggle source

Returns a hash of parsed elements.

static VALUE
date_s__xmlschema(VALUE klass, VALUE str)
{
    return date__xmlschema(str);
}
civil([year=-4712[, month=1[, mday=1[, start=Date::ITALY]]]]) → date click to toggle source
new([year=-4712[, month=1[, mday=1[, start=Date::ITALY]]]]) → date

Creates a date object denoting the given calendar date.

In this class, BCE years are counted astronomically. Thus, the year before the year 1 is the year zero, and the year preceding the year zero is the year -1. The month and the day of month should be a negative or a positive number (as a relative month/day from the end of year/month when negative). They should not be zero.

The last argument should be a Julian day number which denotes the day of calendar reform. Date::ITALY (2299161=1582-10-15), Date::ENGLAND (2361222=1752-09-14), Date::GREGORIAN (the proleptic Gregorian calendar) and Date::JULIAN (the proleptic Julian calendar) can be specified as a day of calendar reform.

Date.new(2001)            #=> #<Date: 2001-01-01 ...>
Date.new(2001,2,3)        #=> #<Date: 2001-02-03 ...>
Date.new(2001,2,-1)       #=> #<Date: 2001-02-28 ...>

See also jd.

static VALUE
date_s_civil(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vm, vd, vsg, y, fr, fr2, ret;
    int m, d;
    double sg;

    rb_scan_args(argc, argv, "04", &vy, &vm, &vd, &vsg);

    y = INT2FIX(-4712);
    m = 1;
    d = 1;
    fr2 = INT2FIX(0);
    sg = DEFAULT_SG;

    switch (argc) {
      case 4:
        val2sg(vsg, sg);
      case 3:
        num2int_with_frac(d, positive_inf);
      case 2:
        m = NUM2INT(vm);
      case 1:
        y = vy;
    }

    if (guess_style(y, sg) < 0) {
        VALUE nth;
        int ry, rm, rd;

        if (!valid_gregorian_p(y, m, d,
                               &nth, &ry,
                               &rm, &rd))
            rb_raise(rb_eArgError, "invalid date");

        ret = d_simple_new_internal(klass,
                                    nth, 0,
                                    sg,
                                    ry, rm, rd,
                                    HAVE_CIVIL);
    }
    else {
        VALUE nth;
        int ry, rm, rd, rjd, ns;

        if (!valid_civil_p(y, m, d, sg,
                           &nth, &ry,
                           &rm, &rd, &rjd,
                           &ns))
            rb_raise(rb_eArgError, "invalid date");

        ret = d_simple_new_internal(klass,
                                    nth, rjd,
                                    sg,
                                    ry, rm, rd,
                                    HAVE_JD | HAVE_CIVIL);
    }
    add_frac();
    return ret;
}
commercial([cwyear=-4712[, cweek=1[, cwday=1[, start=Date::ITALY]]]]) → date click to toggle source

Creates a date object denoting the given week date.

The week and the day of week should be a negative or a positive number (as a relative week/day from the end of year/week when negative). They should not be zero.

Date.commercial(2001)     #=> #<Date: 2001-01-01 ...>
Date.commercial(2002)     #=> #<Date: 2001-12-31 ...>
Date.commercial(2001,5,6) #=> #<Date: 2001-02-03 ...>

See also jd and new.

static VALUE
date_s_commercial(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vw, vd, vsg, y, fr, fr2, ret;
    int w, d;
    double sg;

    rb_scan_args(argc, argv, "04", &vy, &vw, &vd, &vsg);

    y = INT2FIX(-4712);
    w = 1;
    d = 1;
    fr2 = INT2FIX(0);
    sg = DEFAULT_SG;

    switch (argc) {
      case 4:
        val2sg(vsg, sg);
      case 3:
        num2int_with_frac(d, positive_inf);
      case 2:
        w = NUM2INT(vw);
      case 1:
        y = vy;
    }

    {
        VALUE nth;
        int ry, rw, rd, rjd, ns;

        if (!valid_commercial_p(y, w, d, sg,
                                &nth, &ry,
                                &rw, &rd, &rjd,
                                &ns))
            rb_raise(rb_eArgError, "invalid date");

        ret = d_simple_new_internal(klass,
                                    nth, rjd,
                                    sg,
                                    0, 0, 0,
                                    HAVE_JD);
    }
    add_frac();
    return ret;
}
gregorian_leap?(year) → bool click to toggle source
leap?(year) → bool

Returns true if the given year is a leap year of the proleptic Gregorian calendar.

Date.gregorian_leap?(1900)        #=> false
Date.gregorian_leap?(2000)        #=> true

static VALUE
date_s_gregorian_leap_p(VALUE klass, VALUE y)
{
    VALUE nth;
    int ry;

    decode_year(y, -1, &nth, &ry);
    return f_boolcast(c_gregorian_leap_p(ry));
}
httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=ITALY]) → date click to toggle source

Creates a new Date object by parsing from a string according to some RFC 2616 format.

Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT')
                                          #=> #<Date: 2001-02-03 ...>

static VALUE
date_s_httpdate(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("Mon, 01 Jan -4712 00:00:00 GMT");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__httpdate(klass, str);
        return d_new_by_frags(klass, hash, sg);
    }
}
iso8601(string='-4712-01-01'[, start=ITALY]) → date click to toggle source

Creates a new Date object by parsing from a string according to some typical ISO 8601 formats.

Date.iso8601('2001-02-03')        #=> #<Date: 2001-02-03 ...>
Date.iso8601('20010203')          #=> #<Date: 2001-02-03 ...>
Date.iso8601('2001-W05-6')        #=> #<Date: 2001-02-03 ...>

static VALUE
date_s_iso8601(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__iso8601(klass, str);
        return d_new_by_frags(klass, hash, sg);
    }
}
jd([jd=0[, start=Date::ITALY]]) → date click to toggle source

Creates a date object denoting the given chronological Julian day number.

Date.jd(2451944)          #=> #<Date: 2001-02-03 ...>
Date.jd(2451945)          #=> #<Date: 2001-02-04 ...>
Date.jd(0)                #=> #<Date: -4712-01-01 ...>

See also new.

static VALUE
date_s_jd(int argc, VALUE *argv, VALUE klass)
{
    VALUE vjd, vsg, jd, fr, fr2, ret;
    double sg;

    rb_scan_args(argc, argv, "02", &vjd, &vsg);

    jd = INT2FIX(0);
    fr2 = INT2FIX(0);
    sg = DEFAULT_SG;

    switch (argc) {
      case 2:
        val2sg(vsg, sg);
      case 1:
        num2num_with_frac(jd, positive_inf);
    }

    {
        VALUE nth;
        int rjd;

        decode_jd(jd, &nth, &rjd);
        ret = d_simple_new_internal(klass,
                                    nth, rjd,
                                    sg,
                                    0, 0, 0,
                                    HAVE_JD);
    }
    add_frac();
    return ret;
}
jisx0301(string='-4712-01-01'[, start=ITALY]) → date click to toggle source

Creates a new Date object by parsing from a string according to some typical JIS X 0301 formats.

Date.jisx0301('H13.02.03')                #=> #<Date: 2001-02-03 ...>

static VALUE
date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__jisx0301(klass, str);
        return d_new_by_frags(klass, hash, sg);
    }
}
json_create(object) click to toggle source

Deserializes JSON string by converting Julian year y, month m, day d and Day of Calendar Reform sg to Date.

# File ext/json/lib/json/add/date.rb, line 11
def self.json_create(object)
  civil(*object.values_at('y', 'm', 'd', 'sg'))
end
julian_leap?(year) → bool click to toggle source

Returns true if the given year is a leap year of the proleptic Julian calendar.

Date.julian_leap?(1900)           #=> true
Date.julian_leap?(1901)           #=> false

static VALUE
date_s_julian_leap_p(VALUE klass, VALUE y)
{
    VALUE nth;
    int ry;

    decode_year(y, +1, &nth, &ry);
    return f_boolcast(c_julian_leap_p(ry));
}
gregorian_leap?(year) → bool click to toggle source
leap?(year) → bool

Returns true if the given year is a leap year of the proleptic Gregorian calendar.

Date.gregorian_leap?(1900)        #=> false
Date.gregorian_leap?(2000)        #=> true

static VALUE
date_s_gregorian_leap_p(VALUE klass, VALUE y)
{
    VALUE nth;
    int ry;

    decode_year(y, -1, &nth, &ry);
    return f_boolcast(c_gregorian_leap_p(ry));
}
civil([year=-4712[, month=1[, mday=1[, start=Date::ITALY]]]]) → date click to toggle source
new([year=-4712[, month=1[, mday=1[, start=Date::ITALY]]]]) → date

Creates a date object denoting the given calendar date.

In this class, BCE years are counted astronomically. Thus, the year before the year 1 is the year zero, and the year preceding the year zero is the year -1. The month and the day of month should be a negative or a positive number (as a relative month/day from the end of year/month when negative). They should not be zero.

The last argument should be a Julian day number which denotes the day of calendar reform. Date::ITALY (2299161=1582-10-15), Date::ENGLAND (2361222=1752-09-14), Date::GREGORIAN (the proleptic Gregorian calendar) and Date::JULIAN (the proleptic Julian calendar) can be specified as a day of calendar reform.

Date.new(2001)            #=> #<Date: 2001-01-01 ...>
Date.new(2001,2,3)        #=> #<Date: 2001-02-03 ...>
Date.new(2001,2,-1)       #=> #<Date: 2001-02-28 ...>

See also jd.

static VALUE
date_s_civil(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vm, vd, vsg, y, fr, fr2, ret;
    int m, d;
    double sg;

    rb_scan_args(argc, argv, "04", &vy, &vm, &vd, &vsg);

    y = INT2FIX(-4712);
    m = 1;
    d = 1;
    fr2 = INT2FIX(0);
    sg = DEFAULT_SG;

    switch (argc) {
      case 4:
        val2sg(vsg, sg);
      case 3:
        num2int_with_frac(d, positive_inf);
      case 2:
        m = NUM2INT(vm);
      case 1:
        y = vy;
    }

    if (guess_style(y, sg) < 0) {
        VALUE nth;
        int ry, rm, rd;

        if (!valid_gregorian_p(y, m, d,
                               &nth, &ry,
                               &rm, &rd))
            rb_raise(rb_eArgError, "invalid date");

        ret = d_simple_new_internal(klass,
                                    nth, 0,
                                    sg,
                                    ry, rm, rd,
                                    HAVE_CIVIL);
    }
    else {
        VALUE nth;
        int ry, rm, rd, rjd, ns;

        if (!valid_civil_p(y, m, d, sg,
                           &nth, &ry,
                           &rm, &rd, &rjd,
                           &ns))
            rb_raise(rb_eArgError, "invalid date");

        ret = d_simple_new_internal(klass,
                                    nth, rjd,
                                    sg,
                                    ry, rm, rd,
                                    HAVE_JD | HAVE_CIVIL);
    }
    add_frac();
    return ret;
}
ordinal([year=-4712[, yday=1[, start=Date::ITALY]]]) → date click to toggle source

Creates a date object denoting the given ordinal date.

The day of year should be a negative or a positive number (as a relative day from the end of year when negative). It should not be zero.

Date.ordinal(2001)        #=> #<Date: 2001-01-01 ...>
Date.ordinal(2001,34)     #=> #<Date: 2001-02-03 ...>
Date.ordinal(2001,-1)     #=> #<Date: 2001-12-31 ...>

See also jd and new.

static VALUE
date_s_ordinal(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vd, vsg, y, fr, fr2, ret;
    int d;
    double sg;

    rb_scan_args(argc, argv, "03", &vy, &vd, &vsg);

    y = INT2FIX(-4712);
    d = 1;
    fr2 = INT2FIX(0);
    sg = DEFAULT_SG;

    switch (argc) {
      case 3:
        val2sg(vsg, sg);
      case 2:
        num2int_with_frac(d, positive_inf);
      case 1:
        y = vy;
    }

    {
        VALUE nth;
        int ry, rd, rjd, ns;

        if (!valid_ordinal_p(y, d, sg,
                             &nth, &ry,
                             &rd, &rjd,
                             &ns))
            rb_raise(rb_eArgError, "invalid date");

        ret = d_simple_new_internal(klass,
                                     nth, rjd,
                                     sg,
                                     0, 0, 0,
                                     HAVE_JD);
    }
    add_frac();
    return ret;
}
parse(string='-4712-01-01'[, comp=true[, start=ITALY]]) → date click to toggle source

Parses the given representation of date and time, and creates a date object. This method does not function as a validator.

If the optional second argument is true and the detected year is in the range “00” to “99”, considers the year a 2-digit form and makes it full.

Date.parse('2001-02-03')          #=> #<Date: 2001-02-03 ...>
Date.parse('20010203')            #=> #<Date: 2001-02-03 ...>
Date.parse('3rd Feb 2001')        #=> #<Date: 2001-02-03 ...>

static VALUE
date_s_parse(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, comp, sg;

    rb_scan_args(argc, argv, "03", &str, &comp, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01");
      case 1:
        comp = Qtrue;
      case 2:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE argv2[2], hash;

        argv2[0] = str;
        argv2[1] = comp;
        hash = date_s__parse(2, argv2, klass);
        return d_new_by_frags(klass, hash, sg);
    }
}
rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=ITALY]) → date click to toggle source
rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=ITALY]) → date

Creates a new Date object by parsing from a string according to some typical RFC 2822 formats.

Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000')
                                          #=> #<Date: 2001-02-03 ...>

static VALUE
date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__rfc2822(klass, str);
        return d_new_by_frags(klass, hash, sg);
    }
}
rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=ITALY]) → date click to toggle source

Creates a new Date object by parsing from a string according to some typical RFC 3339 formats.

Date.rfc3339('2001-02-03T04:05:06+07:00') #=> #<Date: 2001-02-03 ...>

static VALUE
date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__rfc3339(klass, str);
        return d_new_by_frags(klass, hash, sg);
    }
}
rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=ITALY]) → date click to toggle source
rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=ITALY]) → date

Creates a new Date object by parsing from a string according to some typical RFC 2822 formats.

Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000')
                                          #=> #<Date: 2001-02-03 ...>

static VALUE
date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__rfc2822(klass, str);
        return d_new_by_frags(klass, hash, sg);
    }
}
strptime([string='-4712-01-01'[, format='%F'[, start=ITALY]]]) → date click to toggle source

Parses the given representation of date and time with the given template, and creates a date object. strptime does not support specification of flags and width unlike strftime.

Date.strptime('2001-02-03', '%Y-%m-%d')   #=> #<Date: 2001-02-03 ...>
Date.strptime('03-02-2001', '%d-%m-%Y')   #=> #<Date: 2001-02-03 ...>
Date.strptime('2001-034', '%Y-%j')        #=> #<Date: 2001-02-03 ...>
Date.strptime('2001-W05-6', '%G-W%V-%u')  #=> #<Date: 2001-02-03 ...>
Date.strptime('2001 04 6', '%Y %U %w')    #=> #<Date: 2001-02-03 ...>
Date.strptime('2001 05 6', '%Y %W %u')    #=> #<Date: 2001-02-03 ...>
Date.strptime('sat3feb01', '%a%d%b%y')    #=> #<Date: 2001-02-03 ...>

See also strptime(3) and strftime.

static VALUE
date_s_strptime(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, fmt, sg;

    rb_scan_args(argc, argv, "03", &str, &fmt, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01");
      case 1:
        fmt = rb_str_new2("%F");
      case 2:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE argv2[2], hash;

        argv2[0] = str;
        argv2[1] = fmt;
        hash = date_s__strptime(2, argv2, klass);
        return d_new_by_frags(klass, hash, sg);
    }
}
today([start=Date::ITALY]) → date click to toggle source
today #→ #<Date: 2011-06-11 ..>

Creates a date object denoting the present day.

static VALUE
date_s_today(int argc, VALUE *argv, VALUE klass)
{
    VALUE vsg, nth, ret;
    double sg;
    time_t t;
    struct tm tm;
    int y, ry, m, d;

    rb_scan_args(argc, argv, "01", &vsg);

    if (argc < 1)
        sg = DEFAULT_SG;
    else
        val2sg(vsg, sg);

    if (time(&t) == -1)
        rb_sys_fail("time");
    tzset();
    if (!localtime_r(&t, &tm))
        rb_sys_fail("localtime");

    y = tm.tm_year + 1900;
    m = tm.tm_mon + 1;
    d = tm.tm_mday;

    decode_year(INT2FIX(y), -1, &nth, &ry);

    ret = d_simple_new_internal(klass,
                                nth, 0,
                                GREGORIAN,
                                ry, m, d,
                                HAVE_CIVIL);
    {
        get_d1(ret);
        set_sg(dat, sg);
    }
    return ret;
}
valid_civil?(year, month, mday[, start=Date::ITALY]) → bool click to toggle source
valid_date?(year, month, mday[, start=Date::ITALY]) → bool

Returns true if the given calendar date is valid, and false if not.

Date.valid_date?(2001,2,3)        #=> true
Date.valid_date?(2001,2,29)       #=> false

See also jd and civil.

static VALUE
date_s_valid_civil_p(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vm, vd, vsg;
    VALUE argv2[4];

    rb_scan_args(argc, argv, "31", &vy, &vm, &vd, &vsg);

    argv2[0] = vy;
    argv2[1] = vm;
    argv2[2] = vd;
    if (argc < 4)
        argv2[3] = INT2FIX(DEFAULT_SG);
    else
        argv2[3] = vsg;

    if (NIL_P(valid_civil_sub(4, argv2, klass, 0)))
        return Qfalse;
    return Qtrue;
}
valid_commercial?(cwyear, cweek, cwday[, start=Date::ITALY]) → bool click to toggle source

Returns true if the given week date is valid, and false if not.

Date.valid_commercial?(2001,5,6)  #=> true
Date.valid_commercial?(2001,5,8)  #=> false

See also jd and commercial.

static VALUE
date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vw, vd, vsg;
    VALUE argv2[4];

    rb_scan_args(argc, argv, "31", &vy, &vw, &vd, &vsg);

    argv2[0] = vy;
    argv2[1] = vw;
    argv2[2] = vd;
    if (argc < 4)
        argv2[3] = INT2FIX(DEFAULT_SG);
    else
        argv2[3] = vsg;

    if (NIL_P(valid_commercial_sub(4, argv2, klass, 0)))
        return Qfalse;
    return Qtrue;
}
valid_civil?(year, month, mday[, start=Date::ITALY]) → bool click to toggle source
valid_date?(year, month, mday[, start=Date::ITALY]) → bool

Returns true if the given calendar date is valid, and false if not.

Date.valid_date?(2001,2,3)        #=> true
Date.valid_date?(2001,2,29)       #=> false

See also jd and civil.

static VALUE
date_s_valid_civil_p(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vm, vd, vsg;
    VALUE argv2[4];

    rb_scan_args(argc, argv, "31", &vy, &vm, &vd, &vsg);

    argv2[0] = vy;
    argv2[1] = vm;
    argv2[2] = vd;
    if (argc < 4)
        argv2[3] = INT2FIX(DEFAULT_SG);
    else
        argv2[3] = vsg;

    if (NIL_P(valid_civil_sub(4, argv2, klass, 0)))
        return Qfalse;
    return Qtrue;
}
valid_jd?(jd[, start=Date::ITALY]) → bool click to toggle source

Just returns true. It's nonsense, but is for symmetry.

Date.valid_jd?(2451944)           #=> true

See also jd.

static VALUE
date_s_valid_jd_p(int argc, VALUE *argv, VALUE klass)
{
    VALUE vjd, vsg;
    VALUE argv2[2];

    rb_scan_args(argc, argv, "11", &vjd, &vsg);

    argv2[0] = vjd;
    if (argc < 2)
        argv2[1] = INT2FIX(DEFAULT_SG);
    else
        argv2[1] = vsg;

    if (NIL_P(valid_jd_sub(2, argv2, klass, 0)))
        return Qfalse;
    return Qtrue;
}
valid_ordinal?(year, yday[, start=Date::ITALY]) → bool click to toggle source

Returns true if the given ordinal date is valid, and false if not.

Date.valid_ordinal?(2001,34)      #=> true
Date.valid_ordinal?(2001,366)     #=> false

See also jd and ordinal.

static VALUE
date_s_valid_ordinal_p(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vd, vsg;
    VALUE argv2[3];

    rb_scan_args(argc, argv, "21", &vy, &vd, &vsg);

    argv2[0] = vy;
    argv2[1] = vd;
    if (argc < 3)
        argv2[2] = INT2FIX(DEFAULT_SG);
    else
        argv2[2] = vsg;

    if (NIL_P(valid_ordinal_sub(3, argv2, klass, 0)))
        return Qfalse;
    return Qtrue;
}
xmlschema(string='-4712-01-01'[, start=ITALY]) → date click to toggle source

Creates a new Date object by parsing from a string according to some typical XML Schema formats.

Date.xmlschema('2001-02-03')      #=> #<Date: 2001-02-03 ...>

static VALUE
date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__xmlschema(klass, str);
        return d_new_by_frags(klass, hash, sg);
    }
}

Public Instance Methods

d + other → date click to toggle source

Returns a date object pointing other days after self. The other should be a numeric value. If the other is flonum, assumes its precision is at most nanosecond.

Date.new(2001,2,3) + 1    #=> #<Date: 2001-02-04 ...>
DateTime.new(2001,2,3) + Rational(1,2)
                          #=> #<DateTime: 2001-02-03T12:00:00+00:00 ...>
DateTime.new(2001,2,3) + Rational(-1,2)
                          #=> #<DateTime: 2001-02-02T12:00:00+00:00 ...>
DateTime.jd(0,12) + DateTime.new(2001,2,3).ajd
                          #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>

static VALUE
d_lite_plus(VALUE self, VALUE other)
{
    get_d1(self);

    switch (TYPE(other)) {
      case T_FIXNUM:
        {
            VALUE nth;
            long t;
            int jd;

            nth = m_nth(dat);
            t = FIX2LONG(other);
            if (DIV(t, CM_PERIOD)) {
                nth = f_add(nth, INT2FIX(DIV(t, CM_PERIOD)));
                t = MOD(t, CM_PERIOD);
            }

            if (!t)
                jd = m_jd(dat);
            else {
                jd = m_jd(dat) + (int)t;
                canonicalize_jd(nth, jd);
            }

            if (simple_dat_p(dat))
                return d_simple_new_internal(rb_obj_class(self),
                                             nth, jd,
                                             dat->s.sg,
                                             0, 0, 0,
                                             (dat->s.flags | HAVE_JD) &
                                             ~HAVE_CIVIL);
            else
                return d_complex_new_internal(rb_obj_class(self),
                                              nth, jd,
                                              dat->c.df, dat->c.sf,
                                              dat->c.of, dat->c.sg,
                                              0, 0, 0,
#ifndef USE_PACK
                                              dat->c.hour,
                                              dat->c.min,
                                              dat->c.sec,
#else
                                              EX_HOUR(dat->c.pc),
                                              EX_MIN(dat->c.pc),
                                              EX_SEC(dat->c.pc),
#endif
                                              (dat->c.flags | HAVE_JD) &
                                              ~HAVE_CIVIL);
        }
        break;
      case T_BIGNUM:
        {
            VALUE nth;
            int jd, s;

            if (f_positive_p(other))
                s = +1;
            else {
                s = -1;
                other = f_negate(other);
            }

            nth = f_idiv(other, INT2FIX(CM_PERIOD));
            jd = FIX2INT(f_mod(other, INT2FIX(CM_PERIOD)));

            if (s < 0) {
                nth = f_negate(nth);
                jd = -jd;
            }

            if (!jd)
                jd = m_jd(dat);
            else {
                jd = m_jd(dat) + jd;
                canonicalize_jd(nth, jd);
            }

            if (f_zero_p(nth))
                nth = m_nth(dat);
            else
                nth = f_add(m_nth(dat), nth);

            if (simple_dat_p(dat))
                return d_simple_new_internal(rb_obj_class(self),
                                             nth, jd,
                                             dat->s.sg,
                                             0, 0, 0,
                                             (dat->s.flags | HAVE_JD) &
                                             ~HAVE_CIVIL);
            else
                return d_complex_new_internal(rb_obj_class(self),
                                              nth, jd,
                                              dat->c.df, dat->c.sf,
                                              dat->c.of, dat->c.sg,
                                              0, 0, 0,
#ifndef USE_PACK
                                              dat->c.hour,
                                              dat->c.min,
                                              dat->c.sec,
#else
                                              EX_HOUR(dat->c.pc),
                                              EX_MIN(dat->c.pc),
                                              EX_SEC(dat->c.pc),
#endif
                                              (dat->c.flags | HAVE_JD) &
                                              ~HAVE_CIVIL);
        }
        break;
      case T_FLOAT:
        {
            double jd, o, tmp;
            int s, df;
            VALUE nth, sf;

            o = RFLOAT_VALUE(other);

            if (o > 0)
                s = +1;
            else {
                s = -1;
                o = -o;
            }

            o = modf(o, &tmp);

            if (!floor(tmp / CM_PERIOD)) {
                nth = INT2FIX(0);
                jd = (int)tmp;
            }
            else {
                double i, f;

                f = modf(tmp / CM_PERIOD, &i);
                nth = f_floor(DBL2NUM(i));
                jd = (int)(f * CM_PERIOD);
            }

            o *= DAY_IN_SECONDS;
            o = modf(o, &tmp);
            df = (int)tmp;
            o *= SECOND_IN_NANOSECONDS;
            sf = INT2FIX((int)round(o));

            if (s < 0) {
                jd = -jd;
                df = -df;
                sf = f_negate(sf);
            }

            if (f_zero_p(sf))
                sf = m_sf(dat);
            else {
                sf = f_add(m_sf(dat), sf);
                if (f_lt_p(sf, INT2FIX(0))) {
                    df -= 1;
                    sf = f_add(sf, INT2FIX(SECOND_IN_NANOSECONDS));
                }
                else if (f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) {
                    df += 1;
                    sf = f_sub(sf, INT2FIX(SECOND_IN_NANOSECONDS));
                }
            }

            if (!df)
                df = m_df(dat);
            else {
                df = m_df(dat) + df;
                if (df < 0) {
                    jd -= 1;
                    df += DAY_IN_SECONDS;
                }
                else if (df >= DAY_IN_SECONDS) {
                    jd += 1;
                    df -= DAY_IN_SECONDS;
                }
            }

            if (!jd)
                jd = m_jd(dat);
            else {
                jd = m_jd(dat) + jd;
                canonicalize_jd(nth, jd);
            }

            if (f_zero_p(nth))
                nth = m_nth(dat);
            else
                nth = f_add(m_nth(dat), nth);

            if (!df && f_zero_p(sf) && !m_of(dat))
                return d_simple_new_internal(rb_obj_class(self),
                                             nth, (int)jd,
                                             m_sg(dat),
                                             0, 0, 0,
                                             (dat->s.flags | HAVE_JD) &
                                             ~(HAVE_CIVIL | HAVE_TIME |
                                               COMPLEX_DAT));
            else
                return d_complex_new_internal(rb_obj_class(self),
                                              nth, (int)jd,
                                              df, sf,
                                              m_of(dat), m_sg(dat),
                                              0, 0, 0,
                                              0, 0, 0,
                                              (dat->c.flags |
                                               HAVE_JD | HAVE_DF) &
                                              ~(HAVE_CIVIL | HAVE_TIME));
        }
        break;
      default:
        if (!k_numeric_p(other))
            rb_raise(rb_eTypeError, "expected numeric");
        other = f_to_r(other);
#ifdef CANONICALIZATION_FOR_MATHN
        if (!k_rational_p(other))
            return d_lite_plus(self, other);
#endif
        /* fall through */
      case T_RATIONAL:
        {
            VALUE nth, sf, t;
            int jd, df, s;

            if (wholenum_p(other))
                return d_lite_plus(self, RRATIONAL(other)->num);

            if (f_positive_p(other))
                s = +1;
            else {
                s = -1;
                other = f_negate(other);
            }

            nth = f_idiv(other, INT2FIX(CM_PERIOD));
            t = f_mod(other, INT2FIX(CM_PERIOD));

            jd = FIX2INT(f_idiv(t, INT2FIX(1)));
            t = f_mod(t, INT2FIX(1));

            t = f_mul(t, INT2FIX(DAY_IN_SECONDS));
            df = FIX2INT(f_idiv(t, INT2FIX(1)));
            t = f_mod(t, INT2FIX(1));

            sf = f_mul(t, INT2FIX(SECOND_IN_NANOSECONDS));

            if (s < 0) {
                nth = f_negate(nth);
                jd = -jd;
                df = -df;
                sf = f_negate(sf);
            }

            if (f_zero_p(sf))
                sf = m_sf(dat);
            else {
                sf = f_add(m_sf(dat), sf);
                if (f_lt_p(sf, INT2FIX(0))) {
                    df -= 1;
                    sf = f_add(sf, INT2FIX(SECOND_IN_NANOSECONDS));
                }
                else if (f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) {
                    df += 1;
                    sf = f_sub(sf, INT2FIX(SECOND_IN_NANOSECONDS));
                }
            }

            if (!df)
                df = m_df(dat);
            else {
                df = m_df(dat) + df;
                if (df < 0) {
                    jd -= 1;
                    df += DAY_IN_SECONDS;
                }
                else if (df >= DAY_IN_SECONDS) {
                    jd += 1;
                    df -= DAY_IN_SECONDS;
                }
            }

            if (!jd)
                jd = m_jd(dat);
            else {
                jd = m_jd(dat) + jd;
                canonicalize_jd(nth, jd);
            }

            if (f_zero_p(nth))
                nth = m_nth(dat);
            else
                nth = f_add(m_nth(dat), nth);

            if (!df && f_zero_p(sf) && !m_of(dat))
                return d_simple_new_internal(rb_obj_class(self),
                                             nth, jd,
                                             m_sg(dat),
                                             0, 0, 0,
                                             (dat->s.flags | HAVE_JD) &
                                             ~(HAVE_CIVIL | HAVE_TIME |
                                               COMPLEX_DAT));
            else
                return d_complex_new_internal(rb_obj_class(self),
                                              nth, jd,
                                              df, sf,
                                              m_of(dat), m_sg(dat),
                                              0, 0, 0,
                                              0, 0, 0,
                                              (dat->c.flags |
                                               HAVE_JD | HAVE_DF) &
                                              ~(HAVE_CIVIL | HAVE_TIME));
        }
        break;
    }
}
d - other → date or rational click to toggle source

Returns the difference between the two dates if the other is a date object. If the other is a numeric value, returns a date object pointing other days before self. If the other is flonum, assumes its precision is at most nanosecond.

Date.new(2001,2,3) - 1   #=> #<Date: 2001-02-02 ...>
DateTime.new(2001,2,3) - Rational(1,2)
                         #=> #<DateTime: 2001-02-02T12:00:00+00:00 ...>
Date.new(2001,2,3) - Date.new(2001)
                         #=> (33/1)
DateTime.new(2001,2,3) - DateTime.new(2001,2,2,12)
                         #=> (1/2)

static VALUE
d_lite_minus(VALUE self, VALUE other)
{
    if (k_date_p(other))
        return minus_dd(self, other);

    switch (TYPE(other)) {
      case T_FIXNUM:
        return d_lite_plus(self, LONG2NUM(-FIX2LONG(other)));
      case T_FLOAT:
        return d_lite_plus(self, DBL2NUM(-RFLOAT_VALUE(other)));
      default:
        if (!k_numeric_p(other))
            rb_raise(rb_eTypeError, "expected numeric");
        /* fall through */
      case T_BIGNUM:
      case T_RATIONAL:
        return d_lite_plus(self, f_negate(other));
    }
}
d << n → date click to toggle source

Returns a date object pointing n months before self. The n should be a numeric value.

Date.new(2001,2,3) << 1   #=> #<Date: 2001-01-03 ...>
Date.new(2001,1,31) << 11 #=> #<Date: 2000-02-29 ...>
Date.new(2001,2,3) << -1  #=> #<Date: 2001-03-03 ...>

static VALUE
d_lite_lshift(VALUE self, VALUE other)
{
    return d_lite_rshift(self, f_negate(other));
}
d <=> other → -1, 0, +1 or nil click to toggle source

Compares the two dates and returns -1, zero, 1 or nil. The other should be a date object or a numeric value as an astronomical Julian day number.

Date.new(2001,2,3) <=> Date.new(2001,2,4) #=> -1
Date.new(2001,2,3) <=> Date.new(2001,2,3) #=> 0
Date.new(2001,2,3) <=> Date.new(2001,2,2) #=> 1
Date.new(2001,2,3) <=> Object.new         #=> nil
Date.new(2001,2,3) <=> Rational(4903887,2)#=> 0

See also Comparable.

static VALUE
d_lite_cmp(VALUE self, VALUE other)
{
    if (!k_date_p(other))
        return cmp_gen(self, other);

    {
        get_d2(self, other);

        if (!(simple_dat_p(adat) && simple_dat_p(bdat) &&
              m_gregorian_p(adat) == m_gregorian_p(bdat)))
            return cmp_dd(self, other);

        if (have_jd_p(adat) &&
            have_jd_p(bdat)) {
            VALUE a_nth, b_nth;
            int a_jd, b_jd;

            m_canonicalize_jd(adat);
            m_canonicalize_jd(bdat);
            a_nth = m_nth(adat);
            b_nth = m_nth(bdat);
            if (f_eqeq_p(a_nth, b_nth)) {
                a_jd = m_jd(adat);
                b_jd = m_jd(bdat);
                if (a_jd == b_jd) {
                    return INT2FIX(0);
                }
                else if (a_jd < b_jd) {
                    return INT2FIX(-1);
                }
                else {
                    return INT2FIX(1);
                }
            }
            else if (f_lt_p(a_nth, b_nth)) {
                return INT2FIX(-1);
            }
            else {
                return INT2FIX(1);
            }
        }
        else {
#ifndef USE_PACK
            VALUE a_nth, b_nth;
            int a_year, b_year,
                a_mon, b_mon,
                a_mday, b_mday;
#else
            VALUE a_nth, b_nth;
            int a_year, b_year,
                a_pd, b_pd;
#endif

            m_canonicalize_jd(adat);
            m_canonicalize_jd(bdat);
            a_nth = m_nth(adat);
            b_nth = m_nth(bdat);
            if (f_eqeq_p(a_nth, b_nth)) {
                a_year = m_year(adat);
                b_year = m_year(bdat);
                if (a_year == b_year) {
#ifndef USE_PACK
                    a_mon = m_mon(adat);
                    b_mon = m_mon(bdat);
                    if (a_mon == b_mon) {
                        a_mday = m_mday(adat);
                        b_mday = m_mday(bdat);
                        if (a_mday == b_mday) {
                            return INT2FIX(0);
                        }
                        else if (a_mday < b_mday) {
                            return INT2FIX(-1);
                        }
                        else {
                            return INT2FIX(1);
                        }
                    }
                    else if (a_mon < b_mon) {
                        return INT2FIX(-1);
                    }
                    else {
                        return INT2FIX(1);
                    }
#else
                    a_pd = m_pc(adat);
                    b_pd = m_pc(bdat);
                    if (a_pd == b_pd) {
                        return INT2FIX(0);
                    }
                    else if (a_pd < b_pd) {
                        return INT2FIX(-1);
                    }
                    else {
                        return INT2FIX(1);
                    }
#endif
                }
                else if (a_year < b_year) {
                    return INT2FIX(-1);
                }
                else {
                    return INT2FIX(1);
                }
            }
            else if (f_lt_p(a_nth, b_nth)) {
                return INT2FIX(-1);
            }
            else {
                return INT2FIX(1);
            }
        }
    }
}
d === other → bool click to toggle source

Returns true if they are the same day.

Date.new(2001,2,3) === Date.new(2001,2,3)
                                  #=> true
Date.new(2001,2,3) === Date.new(2001,2,4)
                                  #=> false
DateTime.new(2001,2,3) === DateTime.new(2001,2,3,12)
                                  #=> true
DateTime.new(2001,2,3) === DateTime.new(2001,2,3,0,0,0,'+24:00')
                                  #=> true
DateTime.new(2001,2,3) === DateTime.new(2001,2,4,0,0,0,'+24:00')
                                  #=> false

static VALUE
d_lite_equal(VALUE self, VALUE other)
{
    if (!k_date_p(other))
        return equal_gen(self, other);

    {
        get_d2(self, other);

        if (!(m_gregorian_p(adat) == m_gregorian_p(bdat)))
            return equal_gen(self, other);

        if (have_jd_p(adat) &&
            have_jd_p(bdat)) {
            VALUE a_nth, b_nth;
            int a_jd, b_jd;

            m_canonicalize_jd(adat);
            m_canonicalize_jd(bdat);
            a_nth = m_nth(adat);
            b_nth = m_nth(bdat);
            a_jd = m_local_jd(adat);
            b_jd = m_local_jd(bdat);
            if (f_eqeq_p(a_nth, b_nth) &&
                a_jd == b_jd)
                return Qtrue;
            return Qfalse;
        }
        else {
#ifndef USE_PACK
            VALUE a_nth, b_nth;
            int a_year, b_year,
                a_mon, b_mon,
                a_mday, b_mday;
#else
            VALUE a_nth, b_nth;
            int a_year, b_year,
                a_pd, b_pd;
#endif

            m_canonicalize_jd(adat);
            m_canonicalize_jd(bdat);
            a_nth = m_nth(adat);
            b_nth = m_nth(bdat);
            if (f_eqeq_p(a_nth, b_nth)) {
                a_year = m_year(adat);
                b_year = m_year(bdat);
                if (a_year == b_year) {
#ifndef USE_PACK
                    a_mon = m_mon(adat);
                    b_mon = m_mon(bdat);
                    if (a_mon == b_mon) {
                        a_mday = m_mday(adat);
                        b_mday = m_mday(bdat);
                        if (a_mday == b_mday)
                            return Qtrue;
                    }
#else
                    /* mon and mday only */
                    a_pd = (m_pc(adat) >> MDAY_SHIFT);
                    b_pd = (m_pc(bdat) >> MDAY_SHIFT);
                    if (a_pd == b_pd) {
                        return Qtrue;
                    }
#endif
                }
            }
            return Qfalse;
        }
    }
}
d >> n → date click to toggle source

Returns a date object pointing n months after self. The n should be a numeric value.

Date.new(2001,2,3) >> 1   #=> #<Date: 2001-03-03 ...>
Date.new(2001,1,31) >> 1  #=> #<Date: 2001-02-28 ...>
Date.new(2001,2,3) >> -2  #=> #<Date: 2000-12-03 ...>

static VALUE
d_lite_rshift(VALUE self, VALUE other)
{
    VALUE t, y, nth, rjd2;
    int m, d, rjd;
    double sg;

    get_d1(self);
    t = f_add3(f_mul(m_real_year(dat), INT2FIX(12)),
               INT2FIX(m_mon(dat) - 1),
               other);
    if (FIXNUM_P(t)) {
        long it = FIX2LONG(t);
        y = LONG2NUM(DIV(it, 12));
        it = MOD(it, 12);
        m = (int)it + 1;
    }
    else {
        y = f_idiv(t, INT2FIX(12));
        t = f_mod(t, INT2FIX(12));
        m = FIX2INT(t) + 1;
    }
    d = m_mday(dat);
    sg = m_sg(dat);

    while (1) {
        int ry, rm, rd, ns;

        if (valid_civil_p(y, m, d, sg,
                          &nth, &ry,
                          &rm, &rd, &rjd, &ns))
            break;
        if (--d < 1)
            rb_raise(rb_eArgError, "invalid date");
    }
    encode_jd(nth, rjd, &rjd2);
    return d_lite_plus(self, f_sub(rjd2, m_real_local_jd(dat)));
}
ajd → rational click to toggle source

Returns the astronomical Julian day number. This is a fractional number, which is not adjusted by the offset.

DateTime.new(2001,2,3,4,5,6,'+7').ajd     #=> (11769328217/4800)
DateTime.new(2001,2,2,14,5,6,'-7').ajd    #=> (11769328217/4800)

static VALUE
d_lite_ajd(VALUE self)
{
    get_d1(self);
    return m_ajd(dat);
}
amjd → rational click to toggle source

Returns the astronomical modified Julian day number. This is a fractional number, which is not adjusted by the offset.

DateTime.new(2001,2,3,4,5,6,'+7').amjd    #=> (249325817/4800)
DateTime.new(2001,2,2,14,5,6,'-7').amjd   #=> (249325817/4800)

static VALUE
d_lite_amjd(VALUE self)
{
    get_d1(self);
    return m_amjd(dat);
}
as_json(*) click to toggle source

Returns a hash, that will be turned into a JSON object and represent this object.

# File ext/json/lib/json/add/date.rb, line 19
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'y' => year,
    'm' => month,
    'd' => day,
    'sg' => start,
  }
end
asctime → string click to toggle source
ctime → string

Returns a string in asctime(3) format (but without “n0” at the end). This method is equivalent to strftime('%c').

See also asctime(3) or ctime(3).

static VALUE
d_lite_asctime(VALUE self)
{
    return strftimev("%a %b %e %H:%M:%S %Y", self, set_tmx);
}
asctime → string click to toggle source
ctime → string

Returns a string in asctime(3) format (but without “n0” at the end). This method is equivalent to strftime('%c').

See also asctime(3) or ctime(3).

static VALUE
d_lite_asctime(VALUE self)
{
    return strftimev("%a %b %e %H:%M:%S %Y", self, set_tmx);
}
cwday → fixnum click to toggle source

Returns the day of calendar week (1-7, Monday is 1).

Date.new(2001,2,3).cwday          #=> 6

static VALUE
d_lite_cwday(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_cwday(dat));
}
cweek → fixnum click to toggle source

Returns the calendar week number (1-53).

Date.new(2001,2,3).cweek          #=> 5

static VALUE
d_lite_cweek(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_cweek(dat));
}
cwyear → integer click to toggle source

Returns the calendar week based year.

Date.new(2001,2,3).cwyear         #=> 2001
Date.new(2000,1,1).cwyear         #=> 1999

static VALUE
d_lite_cwyear(VALUE self)
{
    get_d1(self);
    return m_real_cwyear(dat);
}
mday → fixnum click to toggle source
day → fixnum

Returns the day of the month (1-31).

Date.new(2001,2,3).mday           #=> 3

static VALUE
d_lite_mday(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_mday(dat));
}
day_fraction → rational click to toggle source

Returns the fractional part of the day.

DateTime.new(2001,2,3,12).day_fraction    #=> (1/2)

static VALUE
d_lite_day_fraction(VALUE self)
{
    get_d1(self);
    if (simple_dat_p(dat))
        return INT2FIX(0);
    return m_fr(dat);
}
downto(min) → enumerator click to toggle source
downto(min){|date| ...} → self

This method is equivalent to step(min, -1){|date| …}.

static VALUE
d_lite_downto(VALUE self, VALUE min)
{
    VALUE date;

    RETURN_ENUMERATOR(self, 1, &min);

    date = self;
    while (FIX2INT(d_lite_cmp(date, min)) >= 0) {
        rb_yield(date);
        date = d_lite_plus(date, INT2FIX(-1));
    }
    return self;
}
england → date click to toggle source

This method is equivalent to #new_start(Date::ENGLAND).

static VALUE
d_lite_england(VALUE self)
{
    return dup_obj_with_new_start(self, ENGLAND);
}
friday? → bool click to toggle source

Returns true if the date is Friday.

static VALUE
d_lite_friday_p(VALUE self)
{
    get_d1(self);
    return f_boolcast(m_wday(dat) == 5);
}
gregorian → date click to toggle source

This method is equivalent to #new_start(Date::GREGORIAN).

static VALUE
d_lite_gregorian(VALUE self)
{
    return dup_obj_with_new_start(self, GREGORIAN);
}
gregorian? → bool click to toggle source

Retunrs true if the date is on or after the day of calendar reform.

Date.new(1582,10,15).gregorian?          #=> true
(Date.new(1582,10,15) - 1).gregorian?    #=> false

static VALUE
d_lite_gregorian_p(VALUE self)
{
    get_d1(self);
    return f_boolcast(m_gregorian_p(dat));
}
httpdate → string click to toggle source

This method is equivalent to strftime('%a, %d %b %Y %T GMT'). See also RFC 2616.

static VALUE
d_lite_httpdate(VALUE self)
{
    volatile VALUE dup = dup_obj_with_new_offset(self, 0);
    return strftimev("%a, %d %b %Y %T GMT", dup, set_tmx);
}
inspect → string click to toggle source

Returns the value as a string for inspection.

Date.new(2001,2,3).inspect
          #=> "#<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>"
DateTime.new(2001,2,3,4,5,6,'-7').inspect
          #=> "#<DateTime: 2001-02-03T04:05:06-07:00 ((2451944j,39906s,0n),-25200s,2299161j)>"

static VALUE
d_lite_inspect(VALUE self)
{
    get_d1(self);
    {
        VALUE to_s;

        RB_GC_GUARD(to_s) = f_to_s(self);
        return mk_inspect(dat, rb_obj_classname(self), RSTRING_PTR(to_s));
    }
}
iso8601 → string click to toggle source
xmlschema → string

This method is equivalent to strftime('%F').

static VALUE
d_lite_iso8601(VALUE self)
{
    return strftimev("%Y-%m-%d", self, set_tmx);
}
italy → date click to toggle source

This method is equivalent to #new_start(Date::ITALY).

static VALUE
d_lite_italy(VALUE self)
{
    return dup_obj_with_new_start(self, ITALY);
}
jd → integer click to toggle source

Returns the Julian day number. This is a whole number, which is adjusted by the offset as the local time.

DateTime.new(2001,2,3,4,5,6,'+7').jd      #=> 2451944
DateTime.new(2001,2,3,4,5,6,'-7').jd      #=> 2451944

static VALUE
d_lite_jd(VALUE self)
{
    get_d1(self);
    return m_real_local_jd(dat);
}
jisx0301 → string click to toggle source

Returns a string in a JIS X 0301 format.

Date.new(2001,2,3).jisx0301       #=> "H13.02.03"

static VALUE
d_lite_jisx0301(VALUE self)
{
    VALUE s;

    get_d1(self);
    s = jisx0301_date(m_real_local_jd(dat),
                      m_real_year(dat));
    return strftimev(RSTRING_PTR(s), self, set_tmx);
}
julian → date click to toggle source

This method is equivalent to #new_start(Date::JULIAN).

static VALUE
d_lite_julian(VALUE self)
{
    return dup_obj_with_new_start(self, JULIAN);
}
julian? → bool click to toggle source

Retruns true if the date is before the day of calendar reform.

Date.new(1582,10,15).julian?             #=> false
(Date.new(1582,10,15) - 1).julian?       #=> true

static VALUE
d_lite_julian_p(VALUE self)
{
    get_d1(self);
    return f_boolcast(m_julian_p(dat));
}
ld → integer click to toggle source

Returns the Lilian day number. This is a whole number, which is adjusted by the offset as the local time.

Date.new(2001,2,3).ld            #=> 152784

static VALUE
d_lite_ld(VALUE self)
{
    get_d1(self);
    return f_sub(m_real_local_jd(dat), INT2FIX(2299160));
}
leap? → bool click to toggle source

Returns true if the year is a leap year.

Date.new(2000).leap?      #=> true
Date.new(2001).leap?      #=> false

static VALUE
d_lite_leap_p(VALUE self)
{
    int rjd, ns, ry, rm, rd;

    get_d1(self);
    if (m_gregorian_p(dat))
        return f_boolcast(c_gregorian_leap_p(m_year(dat)));

    c_civil_to_jd(m_year(dat), 3, 1, m_virtual_sg(dat),
                  &rjd, &ns);
    c_jd_to_civil(rjd - 1, m_virtual_sg(dat), &ry, &rm, &rd);
    return f_boolcast(rd == 29);
}
mday → fixnum click to toggle source
day → fixnum

Returns the day of the month (1-31).

Date.new(2001,2,3).mday           #=> 3

static VALUE
d_lite_mday(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_mday(dat));
}
mjd → integer click to toggle source

Returns the modified Julian day number. This is a whole number, which is adjusted by the offset as the local time.

DateTime.new(2001,2,3,4,5,6,'+7').mjd     #=> 51943
DateTime.new(2001,2,3,4,5,6,'-7').mjd     #=> 51943

static VALUE
d_lite_mjd(VALUE self)
{
    get_d1(self);
    return f_sub(m_real_local_jd(dat), INT2FIX(2400001));
}
mon → fixnum click to toggle source
month → fixnum

Returns the month (1-12).

Date.new(2001,2,3).mon            #=> 2

static VALUE
d_lite_mon(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_mon(dat));
}
monday? → bool click to toggle source

Returns true if the date is Monday.

static VALUE
d_lite_monday_p(VALUE self)
{
    get_d1(self);
    return f_boolcast(m_wday(dat) == 1);
}
mon → fixnum click to toggle source
month → fixnum

Returns the month (1-12).

Date.new(2001,2,3).mon            #=> 2

static VALUE
d_lite_mon(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_mon(dat));
}
new_start([start=Date::ITALY]) → date click to toggle source

Duplicates self and resets its the day of calendar reform.

d = Date.new(1582,10,15)
d.new_start(Date::JULIAN)         #=> #<Date: 1582-10-05 ...>

static VALUE
d_lite_new_start(int argc, VALUE *argv, VALUE self)
{
    VALUE vsg;
    double sg;

    rb_scan_args(argc, argv, "01", &vsg);

    sg = DEFAULT_SG;
    if (argc >= 1)
        val2sg(vsg, sg);

    return dup_obj_with_new_start(self, sg);
}
next → date click to toggle source

Returns a date object denoting the following day.

static VALUE
d_lite_next(VALUE self)
{
    return d_lite_next_day(0, (VALUE *)NULL, self);
}
next_day([n=1]) → date click to toggle source

This method is equivalent to d + n.

static VALUE
d_lite_next_day(int argc, VALUE *argv, VALUE self)
{
    VALUE n;

    rb_scan_args(argc, argv, "01", &n);
    if (argc < 1)
        n = INT2FIX(1);
    return d_lite_plus(self, n);
}
next_month([n=1]) → date click to toggle source

This method is equivalent to d >> n

static VALUE
d_lite_next_month(int argc, VALUE *argv, VALUE self)
{
    VALUE n;

    rb_scan_args(argc, argv, "01", &n);
    if (argc < 1)
        n = INT2FIX(1);
    return d_lite_rshift(self, n);
}
next_year([n=1]) → date click to toggle source

This method is equivalent to d >> (n * 12)

static VALUE
d_lite_next_year(int argc, VALUE *argv, VALUE self)
{
    VALUE n;

    rb_scan_args(argc, argv, "01", &n);
    if (argc < 1)
        n = INT2FIX(1);
    return d_lite_rshift(self, f_mul(n, INT2FIX(12)));
}
prev_day([n=1]) → date click to toggle source

This method is equivalent to d - n.

static VALUE
d_lite_prev_day(int argc, VALUE *argv, VALUE self)
{
    VALUE n;

    rb_scan_args(argc, argv, "01", &n);
    if (argc < 1)
        n = INT2FIX(1);
    return d_lite_minus(self, n);
}
prev_month([n=1]) → date click to toggle source

This method is equivalent to d << n

static VALUE
d_lite_prev_month(int argc, VALUE *argv, VALUE self)
{
    VALUE n;

    rb_scan_args(argc, argv, "01", &n);
    if (argc < 1)
        n = INT2FIX(1);
    return d_lite_lshift(self, n);
}
prev_year([n=1]) → date click to toggle source

This method is equivalent to d << (n * 12)

static VALUE
d_lite_prev_year(int argc, VALUE *argv, VALUE self)
{
    VALUE n;

    rb_scan_args(argc, argv, "01", &n);
    if (argc < 1)
        n = INT2FIX(1);
    return d_lite_lshift(self, f_mul(n, INT2FIX(12)));
}
rfc2822 → string click to toggle source
rfc822 → string

This method is equivalent to strftime('%a, %-d %b %Y %T %z').

static VALUE
d_lite_rfc2822(VALUE self)
{
    return strftimev("%a, %-d %b %Y %T %z", self, set_tmx);
}
rfc3339 → string click to toggle source

This method is equivalent to strftime('%FT%T%:z').

static VALUE
d_lite_rfc3339(VALUE self)
{
    return strftimev("%Y-%m-%dT%H:%M:%S%:z", self, set_tmx);
}
rfc2822 → string click to toggle source
rfc822 → string

This method is equivalent to strftime('%a, %-d %b %Y %T %z').

static VALUE
d_lite_rfc2822(VALUE self)
{
    return strftimev("%a, %-d %b %Y %T %z", self, set_tmx);
}
saturday? → bool click to toggle source

Returns true if the date is Saturday.

static VALUE
d_lite_saturday_p(VALUE self)
{
    get_d1(self);
    return f_boolcast(m_wday(dat) == 6);
}
start → float click to toggle source

Returns the Julian day number denoting the day of calendar reform.

Date.new(2001,2,3).start                  #=> 2299161.0
Date.new(2001,2,3,Date::GREGORIAN).start  #=> -Infinity

static VALUE
d_lite_start(VALUE self)
{
    get_d1(self);
    return DBL2NUM(m_sg(dat));
}
step(limit[, step=1]) → enumerator click to toggle source
step(limit[, step=1]){|date| ...} → self

Iterates evaluation of the given block, which takes a date object. The limit should be a date object.

Date.new(2001).step(Date.new(2001,-1,-1)).select{|d| d.sunday?}.size
                          #=> 52

static VALUE
d_lite_step(int argc, VALUE *argv, VALUE self)
{
    VALUE limit, step, date;

    rb_scan_args(argc, argv, "11", &limit, &step);

    if (argc < 2)
        step = INT2FIX(1);

#if 0
    if (f_zero_p(step))
        rb_raise(rb_eArgError, "step can't be 0");
#endif

    RETURN_ENUMERATOR(self, argc, argv);

    date = self;
    switch (FIX2INT(f_cmp(step, INT2FIX(0)))) {
      case -1:
        while (FIX2INT(d_lite_cmp(date, limit)) >= 0) {
            rb_yield(date);
            date = d_lite_plus(date, step);
        }
        break;
      case 0:
        while (1)
            rb_yield(date);
        break;
      case 1:
        while (FIX2INT(d_lite_cmp(date, limit)) <= 0) {
            rb_yield(date);
            date = d_lite_plus(date, step);
        }
        break;
      default:
        abort();
    }
    return self;
}
strftime([format='%F']) → string click to toggle source
Formats date according to the directives in the given format
string.
The directives begins with a percent (%Q( character.
Any text not listed as a directive will be passed through to the
output string.

The directive consists of a percent (%) character,
zero or more flags, optional minimum field width,
optional modifier and a conversion specifier
as follows.

  %<flags><width><modifier><conversion>

Flags:
  -  don't pad a numerical output.
  _  use spaces for padding.
  0  use zeros for padding.
  ^  upcase the result string.
  #  change case.

The minimum field width specifies the minimum width.

The modifiers are "E", "O", ":", "::" and ":::".
"E" and "O" are ignored.  No effect to result currently.

Format directives:

  Date (Year, Month, Day):
    %Y - Year with century (can be negative, 4 digits at least)
            -0001, 0000, 1995, 2009, 14292, etc.
    %C - year / 100 (round down.  20 in 2009)
    %y - year % 100 (00..99)

    %m - Month of the year, zero-padded (01..12)
            %_m  blank-padded ( 1..12)
            %-m  no-padded (1..12)
    %B - The full month name (``January'')
            %^B  uppercased (``JANUARY'')
    %b - The abbreviated month name (``Jan'')
            %^b  uppercased (``JAN'')
    %h - Equivalent to %b

    %d - Day of the month, zero-padded (01..31)
            %-d  no-padded (1..31)
    %e - Day of the month, blank-padded ( 1..31)

    %j - Day of the year (001..366)

  Time (Hour, Minute, Second, Subsecond):
    %H - Hour of the day, 24-hour clock, zero-padded (00..23)
    %k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
    %I - Hour of the day, 12-hour clock, zero-padded (01..12)
    %l - Hour of the day, 12-hour clock, blank-padded ( 1..12)
    %P - Meridian indicator, lowercase (``am'' or ``pm'')
    %p - Meridian indicator, uppercase (``AM'' or ``PM'')

    %M - Minute of the hour (00..59)

    %S - Second of the minute (00..59)

    %L - Millisecond of the second (000..999)
    %N - Fractional seconds digits, default is 9 digits (nanosecond)
            %3N  millisecond (3 digits)   %15N femtosecond (15 digits)
            %6N  microsecond (6 digits)   %18N attosecond  (18 digits)
            %9N  nanosecond  (9 digits)   %21N zeptosecond (21 digits)
            %12N picosecond (12 digits)   %24N yoctosecond (24 digits)

  Time zone:
    %z - Time zone as hour and minute offset from UTC (e.g. +0900)
            %:z - hour and minute offset from UTC with a colon (e.g. +09:00)
            %::z - hour, minute and second offset from UTC (e.g. +09:00:00)
            %:::z - hour, minute and second offset from UTC
                                              (e.g. +09, +09:30, +09:30:30)
    %Z - Time zone abbreviation name or something similar information.

  Weekday:
    %A - The full weekday name (``Sunday'')
            %^A  uppercased (``SUNDAY'')
    %a - The abbreviated name (``Sun'')
            %^a  uppercased (``SUN'')
    %u - Day of the week (Monday is 1, 1..7)
    %w - Day of the week (Sunday is 0, 0..6)

  ISO 8601 week-based year and week number:
  The week 1 of YYYY starts with a Monday and includes YYYY-01-04.
  The days in the year before the first week are in the last week of
  the previous year.
    %G - The week-based year
    %g - The last 2 digits of the week-based year (00..99)
    %V - Week number of the week-based year (01..53)

  Week number:
  The week 1 of YYYY starts with a Sunday or Monday (according to %U
  or %W).  The days in the year before the first week are in week 0.
    %U - Week number of the year.  The week starts with Sunday.  (00..53)
    %W - Week number of the year.  The week starts with Monday.  (00..53)

  Seconds since the Unix Epoch:
    %s - Number of seconds since 1970-01-01 00:00:00 UTC.
    %Q - Number of milliseconds since 1970-01-01 00:00:00 UTC.

  Literal string:
    %n - Newline character (\n)
    %t - Tab character (\t)
    %% - Literal ``%'' character

  Combination:
    %c - date and time (%a %b %e %T %Y)
    %D - Date (%m/%d/%y)
    %F - The ISO 8601 date format (%Y-%m-%d)
    %v - VMS date (%e-%b-%Y)
    %x - Same as %D
    %X - Same as %T
    %r - 12-hour time (%I:%M:%S %p)
    %R - 24-hour time (%H:%M)
    %T - 24-hour time (%H:%M:%S)
    %+ - date(1) (%a %b %e %H:%M:%S %Z %Y)

This method is similar to strftime() function defined in ISO C and POSIX.
Several directives (%a, %A, %b, %B, %c, %p, %r, %x, %X, %E*, %O* and %Z)
are locale dependent in the function.
However this method is locale independent.
So, the result may differ even if a same format string is used in other
systems such as C.
It is good practice to avoid %x and %X because there are corresponding
locale independent representations, %D and %T.

Examples:

  d = DateTime.new(2007,11,19,8,37,48,"-06:00")
                            #=> #<DateTime: 2007-11-19T08:37:48-0600 ...>
  d.strftime("Printed on %m/%d/%Y")   #=> "Printed on 11/19/2007"
  d.strftime("at %I:%M%p")            #=> "at 08:37AM"

Various ISO 8601 formats:
  %Y%m%d           => 20071119                  Calendar date (basic)
  %F               => 2007-11-19                Calendar date (extended)
  %Y-%m            => 2007-11                   Calendar date, reduced accuracy, specific month
  %Y               => 2007                      Calendar date, reduced accuracy, specific year
  %C               => 20                        Calendar date, reduced accuracy, specific century
  %Y%j             => 2007323                   Ordinal date (basic)
  %Y-%j            => 2007-323                  Ordinal date (extended)
  %GW%V%u          => 2007W471                  Week date (basic)
  %G-W%V-%u        => 2007-W47-1                Week date (extended)
  %GW%V            => 2007W47                   Week date, reduced accuracy, specific week (basic)
  %G-W%V           => 2007-W47                  Week date, reduced accuracy, specific week (extended)
  %H%M%S           => 083748                    Local time (basic)
  %T               => 08:37:48                  Local time (extended)
  %H%M             => 0837                      Local time, reduced accuracy, specific minute (basic)
  %H:%M            => 08:37                     Local time, reduced accuracy, specific minute (extended)
  %H               => 08                        Local time, reduced accuracy, specific hour
  %H%M%S,%L        => 083748,000                Local time with decimal fraction, comma as decimal sign (basic)
  %T,%L            => 08:37:48,000              Local time with decimal fraction, comma as decimal sign (extended)
  %H%M%S.%L        => 083748.000                Local time with decimal fraction, full stop as decimal sign (basic)
  %T.%L            => 08:37:48.000              Local time with decimal fraction, full stop as decimal sign (extended)
  %H%M%S%z         => 083748-0600               Local time and the difference from UTC (basic)
  %T%:z            => 08:37:48-06:00            Local time and the difference from UTC (extended)
  %Y%m%dT%H%M%S%z  => 20071119T083748-0600      Date and time of day for calendar date (basic)
  %FT%T%:z         => 2007-11-19T08:37:48-06:00 Date and time of day for calendar date (extended)
  %Y%jT%H%M%S%z    => 2007323T083748-0600       Date and time of day for ordinal date (basic)
  %Y-%jT%T%:z      => 2007-323T08:37:48-06:00   Date and time of day for ordinal date (extended)
  %GW%V%uT%H%M%S%z => 2007W471T083748-0600      Date and time of day for week date (basic)
  %G-W%V-%uT%T%:z  => 2007-W47-1T08:37:48-06:00 Date and time of day for week date (extended)
  %Y%m%dT%H%M      => 20071119T0837             Calendar date and local time (basic)
  %FT%R            => 2007-11-19T08:37          Calendar date and local time (extended)
  %Y%jT%H%MZ       => 2007323T0837Z             Ordinal date and UTC of day (basic)
  %Y-%jT%RZ        => 2007-323T08:37Z           Ordinal date and UTC of day (extended)
  %GW%V%uT%H%M%z   => 2007W471T0837-0600        Week date and local time and difference from UTC (basic)
  %G-W%V-%uT%R%:z  => 2007-W47-1T08:37-06:00    Week date and local time and difference from UTC (extended)

See also strftime(3) and strptime.

static VALUE
d_lite_strftime(int argc, VALUE *argv, VALUE self)
{
    return date_strftime_internal(argc, argv, self,
                                  "%Y-%m-%d", set_tmx);
}
next → date click to toggle source

Returns a date object denoting the following day.

static VALUE
d_lite_next(VALUE self)
{
    return d_lite_next_day(0, (VALUE *)NULL, self);
}
sunday? → bool click to toggle source

Returns true if the date is Sunday.

static VALUE
d_lite_sunday_p(VALUE self)
{
    get_d1(self);
    return f_boolcast(m_wday(dat) == 0);
}
thursday? → bool click to toggle source

Returns true if the date is Thursday.

static VALUE
d_lite_thursday_p(VALUE self)
{
    get_d1(self);
    return f_boolcast(m_wday(dat) == 4);
}
to_date → self click to toggle source

Returns self;

static VALUE
date_to_date(VALUE self)
{
    return self;
}
to_datetime → datetime click to toggle source

Returns a DateTime object which denotes self.

static VALUE
date_to_datetime(VALUE self)
{
    get_d1a(self);

    if (simple_dat_p(adat)) {
        VALUE new = d_lite_s_alloc_simple(cDateTime);
        {
            get_d1b(new);
            bdat->s = adat->s;
            return new;
        }
    }
    else {
        VALUE new = d_lite_s_alloc_complex(cDateTime);
        {
            get_d1b(new);
            bdat->c = adat->c;
            bdat->c.df = 0;
            bdat->c.sf = INT2FIX(0);
#ifndef USE_PACK
            bdat->c.hour = 0;
            bdat->c.min = 0;
            bdat->c.sec = 0;
#else
            bdat->c.pc = PACK5(EX_MON(adat->c.pc), EX_MDAY(adat->c.pc),
                               0, 0, 0);
            bdat->c.flags |= HAVE_DF | HAVE_TIME;
#endif
            return new;
        }
    }
}
to_json(*args) click to toggle source

Stores class name (Date) with Julian year y, month m, day d and Day of Calendar Reform sg as JSON string

# File ext/json/lib/json/add/date.rb, line 31
def to_json(*args)
  as_json.to_json(*args)
end
to_s → string click to toggle source

Returns a string in an ISO 8601 format (This method doesn't use the expanded representations).

Date.new(2001,2,3).to_s  #=> "2001-02-03"

static VALUE
d_lite_to_s(VALUE self)
{
    return strftimev("%Y-%m-%d", self, set_tmx);
}
to_time → time click to toggle source

Returns a Time object which denotes self.

static VALUE
date_to_time(VALUE self)
{
    get_d1(self);

    return f_local3(rb_cTime,
                    m_real_year(dat),
                    INT2FIX(m_mon(dat)),
                    INT2FIX(m_mday(dat)));
}
tuesday? → bool click to toggle source

Returns true if the date is Tuesday.

static VALUE
d_lite_tuesday_p(VALUE self)
{
    get_d1(self);
    return f_boolcast(m_wday(dat) == 2);
}
upto(max) → enumerator click to toggle source
upto(max){|date| ...} → self

This method is equivalent to step(max, 1){|date| …}.

static VALUE
d_lite_upto(VALUE self, VALUE max)
{
    VALUE date;

    RETURN_ENUMERATOR(self, 1, &max);

    date = self;
    while (FIX2INT(d_lite_cmp(date, max)) <= 0) {
        rb_yield(date);
        date = d_lite_plus(date, INT2FIX(1));
    }
    return self;
}
wday → fixnum click to toggle source

Returns the day of week (0-6, Sunday is zero).

Date.new(2001,2,3).wday           #=> 6

static VALUE
d_lite_wday(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_wday(dat));
}
wednesday? → bool click to toggle source

Returns true if the date is Wednesday.

static VALUE
d_lite_wednesday_p(VALUE self)
{
    get_d1(self);
    return f_boolcast(m_wday(dat) == 3);
}
iso8601 → string click to toggle source
xmlschema → string

This method is equivalent to strftime('%F').

static VALUE
d_lite_iso8601(VALUE self)
{
    return strftimev("%Y-%m-%d", self, set_tmx);
}
yday → fixnum click to toggle source

Returns the day of the year (1-366).

Date.new(2001,2,3).yday           #=> 34

static VALUE
d_lite_yday(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_yday(dat));
}
year → integer click to toggle source

Returns the year.

Date.new(2001,2,3).year           #=> 2001
(Date.new(1,1,1) - 1).year        #=> 0

static VALUE
d_lite_year(VALUE self)
{
    get_d1(self);
    return m_real_year(dat);
}


class DateTime - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class DateTime

date and datetime class - Tadayoshi Funaba 1998-2011

'date' provides two classes Date and DateTime.

Terms and definitions

Some terms and definitions are based on ISO 8601 and JIS X 0301.

calendar date

The calendar date is a particular day of a calendar year, identified by its ordinal number within a calendar month within that year.

In those classes, this is so-called “civil”.

ordinal date

The ordinal date is a particular day of a calendar year identified by its ordinal number within the year.

In those classes, this is so-called “ordinal”.

week date

The week date is a date identified by calendar week and day numbers.

The calendar week is a seven day period within a calendar year, starting on a Monday and identified by its ordinal number within the year; the first calendar week of the year is the one that includes the first Thursday of that year. In the Gregorian calendar, this is equivalent to the week which includes January 4.

In those classes, this so-called “commercial”.

julian day number

The Julian day number is in elapsed days since noon (Greenwich mean time) on January 1, 4713 BCE (in the Julian calendar).

In this document, the astronomical Julian day number is same as the original Julian day number. And the chronological Julian day number is a variation of the Julian day number. Its days begin at midnight on local time.

In this document, when the term “Julian day number” simply appears, it just refers to “chronological Julian day number”, not the original.

In those classes, those are so-called “ajd” and “jd”.

modified julian day number

The modified Julian day number is in elapsed days since midnight (Coordinated universal time) on November 17, 1858 CE (in the Gregorian calendar).

In this document, the astronomical modified Julian day number is same as the original modified Julian day number. And the chronological modified Julian day number is a variation of the modified Julian day number. Its days begin at midnight on local time.

In this document, when the term “modified Julian day number” simply appears, it just refers to “chronological modified Julian day number”, not the original.

In those classes, this is so-called “mjd”.

Date

A subclass of Object includes Comparable module, easily handles date.

Date object is created with Date.new, Date.jd, Date.ordinal, Date.commercial, Date.parse, Date.strptime, Date.today, Time#to_date or etc.

require 'date'

Date.new(2001,2,3)           #=> #<Date: 2001-02-03 ...>
Date.jd(2451944)             #=> #<Date: 2001-02-03 ...>
Date.ordinal(2001,34)        #=> #<Date: 2001-02-03 ...>
Date.commercial(2001,5,6)    #=> #<Date: 2001-02-03 ...>
Date.parse('2001-02-03')     #=> #<Date: 2001-02-03 ...>
Date.strptime('03-02-2001', '%d-%m-%Y')
                             #=> #<Date: 2001-02-03 ...>
Time.new(2001,2,3).to_date   #=> #<Date: 2001-02-03 ...>

All date objects are immutable; hence cannot modify themselves.

The concept of this date object can be represented as a tuple of the day count, the offset and the day of calendar reform.

The day count denotes the absolute position of a temporal dimension. The offset is relative adjustment, which determines decoded local time with the day count. The day of calendar reform denotes the start day of the new style. The old style of the West is the Julian calendar which was adopted by Caersar. The new style is the Gregorian calendar, which is the current civil calendar of many countries.

The day count is virtually the astronomical Julian day number. The offset in this class is usually zero, and cannot be specified directly.

An optional argument the day of calendar reform (start) as a Julian day number, which should be 2298874 to 2426355 or -/+oo. The default value is Date::ITALY (2299161=1582-10-15). See also sample/cal.rb.

$ ruby sample/cal.rb -c it 10 1582
    October 1582
 S  M Tu  W Th  F  S
    1  2  3  4 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

$ ruby sample/cal.rb -c gb  9 1752
   September 1752
 S  M Tu  W Th  F  S
       1  2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Date object has various methods. See each reference.

d = Date.parse('3rd Feb 2001')
                             #=> #<Date: 2001-02-03 ...>
d.year                       #=> 2001
d.mon                        #=> 2
d.mday                       #=> 3
d.wday                       #=> 6
d += 1                       #=> #<Date: 2001-02-04 ...>
d.strftime('%a %d %b %Y')    #=> "Sun 04 Feb 2001"

DateTime

A subclass of Date easily handles date, hour, minute, second and offset.

DateTime does not consider any leapseconds, does not track any summer time rules.

DateTime object is created with ::new, ::jd, ::ordinal, ::commercial, ::parse, ::strptime, ::now, Time#to_datetime or etc.

require 'date'

DateTime.new(2001,2,3,4,5,6)
                     #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>

The last element of day, hour, minute or senond can be fractional number. The fractional number's precision is assumed at most nanosecond.

DateTime.new(2001,2,3.5)
                     #=> #<DateTime: 2001-02-03T12:00:00+00:00 ...>

An optional argument the offset indicates the difference between the local time and UTC. For example, Rational(3,24) represents ahead of 3 hours of UTC, Rational(-5,24) represents behind of 5 hours of UTC. The offset should be -1 to +1, and its precision is assumed at most second. The default value is zero (equals to UTC).

DateTime.new(2001,2,3,4,5,6,Rational(3,24))
                     #=> #<DateTime: 2001-02-03T04:05:06+03:00 ...>

also accepts string form.

DateTime.new(2001,2,3,4,5,6,'+03:00')
                     #=> #<DateTime: 2001-02-03T04:05:06+03:00 ...>

An optional argument the day of calendar reform (start) denotes a Julian day number, which should be 2298874 to 2426355 or -/+oo. The default value is Date::ITALY (2299161=1582-10-15).

DateTime object has various methods. See each reference.

d = DateTime.parse('3rd Feb 2001 04:05:06+03:30')
                     #=> #<DateTime: 2001-02-03T04:05:06+03:30 ...>
d.hour               #=> 4
d.min                #=> 5
d.sec                #=> 6
d.offset             #=> (7/48)
d.zone               #=> "+03:30"
d += Rational('1.5')
                     #=> #<DateTime: 2001-02-04%16:05:06+03:30 ...>
d = d.new_offset('+09:00')
                     #=> #<DateTime: 2001-02-04%21:35:06+09:00 ...>
d.strftime('%I:%M:%S %p')
                     #=> "09:35:06 PM"
d > DateTime.new(1999)
                     #=> true

DateTime serialization/deserialization

In Files

  • ext/date/date_core.c
  • ext/json/lib/json/add/date_time.rb

Parent

Date

Public Class Methods

_strptime(string[, format='%FT%T%z']) → hash click to toggle source

Parses the given representation of date and time with the given template, and returns a hash of parsed elements. _strptime does not support specification of flags and width unlike strftime.

See also strptime(3) and strftime.
static VALUE
datetime_s__strptime(int argc, VALUE *argv, VALUE klass)
{
    return date_s__strptime_internal(argc, argv, klass, "%FT%T%z");
}
civil([year=-4712[, month=1[, mday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) → datetime click to toggle source
new([year=-4712[, month=1[, mday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) → datetime

Creates a date-time object denoting the given calendar date.

DateTime.new(2001,2,3)    #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>
DateTime.new(2001,2,3,4,5,6,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.new(2001,-11,-26,-20,-55,-54,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

static VALUE
datetime_s_civil(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vm, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
    int m, d, h, min, s, rof;
    double sg;

    rb_scan_args(argc, argv, "08", &vy, &vm, &vd, &vh, &vmin, &vs, &vof, &vsg);

    y = INT2FIX(-4712);
    m = 1;
    d = 1;

    h = min = s = 0;
    fr2 = INT2FIX(0);
    rof = 0;
    sg = DEFAULT_SG;

    switch (argc) {
      case 8:
        val2sg(vsg, sg);
      case 7:
        val2off(vof, rof);
      case 6:
        num2int_with_frac(s, positive_inf);
      case 5:
        num2int_with_frac(min, 5);
      case 4:
        num2int_with_frac(h, 4);
      case 3:
        num2int_with_frac(d, 3);
      case 2:
        m = NUM2INT(vm);
      case 1:
        y = vy;
    }

    if (guess_style(y, sg) < 0) {
        VALUE nth;
        int ry, rm, rd, rh, rmin, rs;

        if (!valid_gregorian_p(y, m, d,
                               &nth, &ry,
                               &rm, &rd))
            rb_raise(rb_eArgError, "invalid date");
        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(rb_eArgError, "invalid date");
        canon24oc();

        ret = d_complex_new_internal(klass,
                                     nth, 0,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     ry, rm, rd,
                                     rh, rmin, rs,
                                     HAVE_CIVIL | HAVE_TIME);
    }
    else {
        VALUE nth;
        int ry, rm, rd, rh, rmin, rs, rjd, rjd2, ns;

        if (!valid_civil_p(y, m, d, sg,
                           &nth, &ry,
                           &rm, &rd, &rjd,
                           &ns))
            rb_raise(rb_eArgError, "invalid date");
        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(rb_eArgError, "invalid date");
        canon24oc();

        rjd2 = jd_local_to_utc(rjd,
                               time_to_df(rh, rmin, rs),
                               rof);

        ret = d_complex_new_internal(klass,
                                     nth, rjd2,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     ry, rm, rd,
                                     rh, rmin, rs,
                                     HAVE_JD | HAVE_CIVIL | HAVE_TIME);
    }
    add_frac();
    return ret;
}
commercial([cwyear=-4712[, cweek=1[, cwday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) → datetime click to toggle source

Creates a date-time object denoting the given week date.

DateTime.commercial(2001) #=> #<DateTime: 2001-01-01T00:00:00+00:00 ...>
DateTime.commercial(2002) #=> #<DateTime: 2001-12-31T00:00:00+00:00 ...>
DateTime.commercial(2001,5,6,4,5,6,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

static VALUE
datetime_s_commercial(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vw, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
    int w, d, h, min, s, rof;
    double sg;

    rb_scan_args(argc, argv, "08", &vy, &vw, &vd, &vh, &vmin, &vs, &vof, &vsg);

    y = INT2FIX(-4712);
    w = 1;
    d = 1;

    h = min = s = 0;
    fr2 = INT2FIX(0);
    rof = 0;
    sg = DEFAULT_SG;

    switch (argc) {
      case 8:
        val2sg(vsg, sg);
      case 7:
        val2off(vof, rof);
      case 6:
        num2int_with_frac(s, positive_inf);
      case 5:
        num2int_with_frac(min, 5);
      case 4:
        num2int_with_frac(h, 4);
      case 3:
        num2int_with_frac(d, 3);
      case 2:
        w = NUM2INT(vw);
      case 1:
        y = vy;
    }

    {
        VALUE nth;
        int ry, rw, rd, rh, rmin, rs, rjd, rjd2, ns;

        if (!valid_commercial_p(y, w, d, sg,
                                &nth, &ry,
                                &rw, &rd, &rjd,
                                &ns))
            rb_raise(rb_eArgError, "invalid date");
        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(rb_eArgError, "invalid date");
        canon24oc();

        rjd2 = jd_local_to_utc(rjd,
                               time_to_df(rh, rmin, rs),
                               rof);

        ret = d_complex_new_internal(klass,
                                     nth, rjd2,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     0, 0, 0,
                                     rh, rmin, rs,
                                     HAVE_JD | HAVE_TIME);
    }
    add_frac();
    return ret;
}
httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=ITALY]) → datetime click to toggle source

Creates a new Date object by parsing from a string according to some RFC 2616 format.

DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT')
                          #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>

static VALUE
datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("Mon, 01 Jan -4712 00:00:00 GMT");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__httpdate(klass, str);
        return dt_new_by_frags(klass, hash, sg);
    }
}
iso8601(string='-4712-01-01T00:00:00+00:00'[, start=ITALY]) → datetime click to toggle source

Creates a new Date object by parsing from a string according to some typical ISO 8601 formats.

DateTime.iso8601('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.iso8601('20010203T040506+0700')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.iso8601('2001-W05-6T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

static VALUE
datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__iso8601(klass, str);
        return dt_new_by_frags(klass, hash, sg);
    }
}
jd([jd=0[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]) → datetime click to toggle source

Creates a datetime object denoting the given chronological Julian day number.

DateTime.jd(2451944)      #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>
DateTime.jd(2451945)      #=> #<DateTime: 2001-02-04T00:00:00+00:00 ...>
DateTime.jd(Rational('0.5'))
                          #=> #<DateTime: -4712-01-01T12:00:00+00:00 ...>

static VALUE
datetime_s_jd(int argc, VALUE *argv, VALUE klass)
{
    VALUE vjd, vh, vmin, vs, vof, vsg, jd, fr, fr2, ret;
    int h, min, s, rof;
    double sg;

    rb_scan_args(argc, argv, "06", &vjd, &vh, &vmin, &vs, &vof, &vsg);

    jd = INT2FIX(0);

    h = min = s = 0;
    fr2 = INT2FIX(0);
    rof = 0;
    sg = DEFAULT_SG;

    switch (argc) {
      case 6:
        val2sg(vsg, sg);
      case 5:
        val2off(vof, rof);
      case 4:
        num2int_with_frac(s, positive_inf);
      case 3:
        num2int_with_frac(min, 3);
      case 2:
        num2int_with_frac(h, 2);
      case 1:
        num2num_with_frac(jd, 1);
    }

    {
        VALUE nth;
        int rh, rmin, rs, rjd, rjd2;

        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(rb_eArgError, "invalid date");
        canon24oc();

        decode_jd(jd, &nth, &rjd);
        rjd2 = jd_local_to_utc(rjd,
                               time_to_df(rh, rmin, rs),
                               rof);

        ret = d_complex_new_internal(klass,
                                     nth, rjd2,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     0, 0, 0,
                                     rh, rmin, rs,
                                     HAVE_JD | HAVE_TIME);
    }
    add_frac();
    return ret;
}
jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=ITALY]) → datetime click to toggle source

Creates a new Date object by parsing from a string according to some typical JIS X 0301 formats.

DateTime.jisx0301('H13.02.03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

static VALUE
datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__jisx0301(klass, str);
        return dt_new_by_frags(klass, hash, sg);
    }
}
json_create(object) click to toggle source

Deserializes JSON string by converting year y, month m, day d, hour H, minute M, second S, offset of and Day of Calendar Reform sg to DateTime.

# File ext/json/lib/json/add/date_time.rb, line 12
def self.json_create(object)
  args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
  of_a, of_b = object['of'].split('/')
  if of_b and of_b != '0'
    args << Rational(of_a.to_i, of_b.to_i)
  else
    args << of_a
  end
  args << object['sg']
  civil(*args)
end
civil([year=-4712[, month=1[, mday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) → datetime click to toggle source
new([year=-4712[, month=1[, mday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) → datetime

Creates a date-time object denoting the given calendar date.

DateTime.new(2001,2,3)    #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>
DateTime.new(2001,2,3,4,5,6,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.new(2001,-11,-26,-20,-55,-54,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

static VALUE
datetime_s_civil(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vm, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
    int m, d, h, min, s, rof;
    double sg;

    rb_scan_args(argc, argv, "08", &vy, &vm, &vd, &vh, &vmin, &vs, &vof, &vsg);

    y = INT2FIX(-4712);
    m = 1;
    d = 1;

    h = min = s = 0;
    fr2 = INT2FIX(0);
    rof = 0;
    sg = DEFAULT_SG;

    switch (argc) {
      case 8:
        val2sg(vsg, sg);
      case 7:
        val2off(vof, rof);
      case 6:
        num2int_with_frac(s, positive_inf);
      case 5:
        num2int_with_frac(min, 5);
      case 4:
        num2int_with_frac(h, 4);
      case 3:
        num2int_with_frac(d, 3);
      case 2:
        m = NUM2INT(vm);
      case 1:
        y = vy;
    }

    if (guess_style(y, sg) < 0) {
        VALUE nth;
        int ry, rm, rd, rh, rmin, rs;

        if (!valid_gregorian_p(y, m, d,
                               &nth, &ry,
                               &rm, &rd))
            rb_raise(rb_eArgError, "invalid date");
        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(rb_eArgError, "invalid date");
        canon24oc();

        ret = d_complex_new_internal(klass,
                                     nth, 0,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     ry, rm, rd,
                                     rh, rmin, rs,
                                     HAVE_CIVIL | HAVE_TIME);
    }
    else {
        VALUE nth;
        int ry, rm, rd, rh, rmin, rs, rjd, rjd2, ns;

        if (!valid_civil_p(y, m, d, sg,
                           &nth, &ry,
                           &rm, &rd, &rjd,
                           &ns))
            rb_raise(rb_eArgError, "invalid date");
        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(rb_eArgError, "invalid date");
        canon24oc();

        rjd2 = jd_local_to_utc(rjd,
                               time_to_df(rh, rmin, rs),
                               rof);

        ret = d_complex_new_internal(klass,
                                     nth, rjd2,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     ry, rm, rd,
                                     rh, rmin, rs,
                                     HAVE_JD | HAVE_CIVIL | HAVE_TIME);
    }
    add_frac();
    return ret;
}
now([start=Date::ITALY]) → datetime click to toggle source

Creates a date-time object denoting the present time.

DateTime.now              #=> #<DateTime: 2011-06-11T21:20:44+09:00 ...>

static VALUE
datetime_s_now(int argc, VALUE *argv, VALUE klass)
{
    VALUE vsg, nth, ret;
    double sg;
#ifdef HAVE_CLOCK_GETTIME
    struct timespec ts;
#else
    struct timeval tv;
#endif
    time_t sec;
    struct tm tm;
    long sf, of;
    int y, ry, m, d, h, min, s;

    rb_scan_args(argc, argv, "01", &vsg);

    if (argc < 1)
        sg = DEFAULT_SG;
    else
        sg = NUM2DBL(vsg);

#ifdef HAVE_CLOCK_GETTIME
    if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
        rb_sys_fail("clock_gettime");
    sec = ts.tv_sec;
#else
    if (gettimeofday(&tv, NULL) == -1)
        rb_sys_fail("gettimeofday");
    sec = tv.tv_sec;
#endif
    tzset();
    if (!localtime_r(&sec, &tm))
        rb_sys_fail("localtime");

    y = tm.tm_year + 1900;
    m = tm.tm_mon + 1;
    d = tm.tm_mday;
    h = tm.tm_hour;
    min = tm.tm_min;
    s = tm.tm_sec;
    if (s == 60)
        s = 59;
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
    of = tm.tm_gmtoff;
#elif defined(HAVE_VAR_TIMEZONE)
#ifdef HAVE_VAR_ALTZONE
    of = (long)-((tm.tm_isdst > 0) ? altzone : timezone);
#else
    of = (long)-timezone;
    if (tm.tm_isdst) {
        time_t sec2;

        tm.tm_isdst = 0;
        sec2 = mktime(&tm);
        of += (long)difftime(sec2, sec);
    }
#endif
#elif defined(HAVE_TIMEGM)
    {
        time_t sec2;

        sec2 = timegm(&tm);
        of = (long)difftime(sec2, sec);
    }
#else
    {
        struct tm tm2;
        time_t sec2;

        if (!gmtime_r(&sec, &tm2))
            rb_sys_fail("gmtime");
        tm2.tm_isdst = tm.tm_isdst;
        sec2 = mktime(&tm2);
        of = (long)difftime(sec, sec2);
    }
#endif
#ifdef HAVE_CLOCK_GETTIME
    sf = ts.tv_nsec;
#else
    sf = tv.tv_usec * 1000;
#endif

    if (of < -DAY_IN_SECONDS || of > DAY_IN_SECONDS) {
        of = 0;
        rb_warning("invalid offset is ignored");
    }

    decode_year(INT2FIX(y), -1, &nth, &ry);

    ret = d_complex_new_internal(klass,
                                 nth, 0,
                                 0, LONG2NUM(sf),
                                 (int)of, GREGORIAN,
                                 ry, m, d,
                                 h, min, s,
                                 HAVE_CIVIL | HAVE_TIME);
    {
        get_d1(ret);
        set_sg(dat, sg);
    }
    return ret;
}
ordinal([year=-4712[, yday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]) → datetime click to toggle source

Creates a date-time object denoting the given ordinal date.

DateTime.ordinal(2001,34) #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>
DateTime.ordinal(2001,34,4,5,6,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.ordinal(2001,-332,-20,-55,-54,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

static VALUE
datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
    int d, h, min, s, rof;
    double sg;

    rb_scan_args(argc, argv, "07", &vy, &vd, &vh, &vmin, &vs, &vof, &vsg);

    y = INT2FIX(-4712);
    d = 1;

    h = min = s = 0;
    fr2 = INT2FIX(0);
    rof = 0;
    sg = DEFAULT_SG;

    switch (argc) {
      case 7:
        val2sg(vsg, sg);
      case 6:
        val2off(vof, rof);
      case 5:
        num2int_with_frac(s, positive_inf);
      case 4:
        num2int_with_frac(min, 4);
      case 3:
        num2int_with_frac(h, 3);
      case 2:
        num2int_with_frac(d, 2);
      case 1:
        y = vy;
    }

    {
        VALUE nth;
        int ry, rd, rh, rmin, rs, rjd, rjd2, ns;

        if (!valid_ordinal_p(y, d, sg,
                             &nth, &ry,
                             &rd, &rjd,
                             &ns))
            rb_raise(rb_eArgError, "invalid date");
        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(rb_eArgError, "invalid date");
        canon24oc();

        rjd2 = jd_local_to_utc(rjd,
                               time_to_df(rh, rmin, rs),
                               rof);

        ret = d_complex_new_internal(klass,
                                     nth, rjd2,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     0, 0, 0,
                                     rh, rmin, rs,
                                     HAVE_JD | HAVE_TIME);
    }
    add_frac();
    return ret;
}
parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=ITALY]]) → datetime click to toggle source

Parses the given representation of date and time, and creates a date object. This method does not function as a validator.

If the optional second argument is true and the detected year is in the range “00” to “99”, makes it full.

DateTime.parse('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.parse('20010203T040506+0700')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.parse('3rd Feb 2001 04:05:06 PM')
                          #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>

static VALUE
datetime_s_parse(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, comp, sg;

    rb_scan_args(argc, argv, "03", &str, &comp, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        comp = Qtrue;
      case 2:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE argv2[2], hash;

        argv2[0] = str;
        argv2[1] = comp;
        hash = date_s__parse(2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}
rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=ITALY]) → datetime click to toggle source
rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=ITALY]) → datetime

Creates a new Date object by parsing from a string according to some typical RFC 2822 formats.

DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700')
                         #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

static VALUE
datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__rfc2822(klass, str);
        return dt_new_by_frags(klass, hash, sg);
    }
}
rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=ITALY]) → datetime click to toggle source

Creates a new Date object by parsing from a string according to some typical RFC 3339 formats.

DateTime.rfc3339('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

static VALUE
datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__rfc3339(klass, str);
        return dt_new_by_frags(klass, hash, sg);
    }
}
rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=ITALY]) → datetime click to toggle source
rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=ITALY]) → datetime

Creates a new Date object by parsing from a string according to some typical RFC 2822 formats.

DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700')
                         #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

static VALUE
datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__rfc2822(klass, str);
        return dt_new_by_frags(klass, hash, sg);
    }
}
strptime([string='-4712-01-01T00:00:00+00:00'[, format='%FT%T%z'[ ,start=ITALY]]]) → datetime click to toggle source

Parses the given representation of date and time with the given template, and creates a date object. strptime does not support specification of flags and width unlike strftime.

DateTime.strptime('2001-02-03T04:05:06+07:00', '%Y-%m-%dT%H:%M:%S%z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('03-02-2001 04:05:06 PM', '%d-%m-%Y %I:%M:%S %p')
                          #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>
DateTime.strptime('2001-W05-6T04:05:06+07:00', '%G-W%V-%uT%H:%M:%S%z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('2001 04 6 04 05 06 +7', '%Y %U %w %H %M %S %z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('2001 05 6 04 05 06 +7', '%Y %W %u %H %M %S %z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('-1', '%s')
                          #=> #<DateTime: 1969-12-31T23:59:59+00:00 ...>
DateTime.strptime('-1000', '%Q')
                          #=> #<DateTime: 1969-12-31T23:59:59+00:00 ...>
DateTime.strptime('sat3feb014pm+7', '%a%d%b%y%H%p%z')
                          #=> #<DateTime: 2001-02-03T16:00:00+07:00 ...>

See also strptime(3) and strftime.

static VALUE
datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, fmt, sg;

    rb_scan_args(argc, argv, "03", &str, &fmt, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        fmt = rb_str_new2("%FT%T%z");
      case 2:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE argv2[2], hash;

        argv2[0] = str;
        argv2[1] = fmt;
        hash = date_s__strptime(2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}
xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=ITALY]) → datetime click to toggle source

Creates a new Date object by parsing from a string according to some typical XML Schema formats.

DateTime.xmlschema('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

static VALUE
datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE hash = date_s__xmlschema(klass, str);
        return dt_new_by_frags(klass, hash, sg);
    }
}

Public Instance Methods

as_json(*) click to toggle source

Returns a hash, that will be turned into a JSON object and represent this object.

# File ext/json/lib/json/add/date_time.rb, line 28
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'y' => year,
    'm' => month,
    'd' => day,
    'H' => hour,
    'M' => min,
    'S' => sec,
    'of' => offset.to_s,
    'sg' => start,
  }
end
iso8601([n=0]) → string click to toggle source
xmlschema([n=0]) → string

This method is equivalent to strftime('%FT%T'). The optional argument n is length of fractional seconds.

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').iso8601(9)
                          #=> "2001-02-03T04:05:06.123456789+07:00"

static VALUE
dt_lite_iso8601(int argc, VALUE *argv, VALUE self)
{
    VALUE n;

    rb_scan_args(argc, argv, "01", &n);

    if (argc < 1)
        n = INT2FIX(0);

    return f_add(strftimev("%Y-%m-%d", self, set_tmx),
                 iso8601_timediv(self, n));
}
jisx0301([n=0]) → string click to toggle source

Returns a string in a JIS X 0301 format. The optional argument n is length of fractional seconds.

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').jisx0301(9)
                          #=> "H13.02.03T04:05:06.123456789+07:00"

static VALUE
dt_lite_jisx0301(int argc, VALUE *argv, VALUE self)
{
    VALUE n, s;

    rb_scan_args(argc, argv, "01", &n);

    if (argc < 1)
        n = INT2FIX(0);

    {
        get_d1(self);
        s = jisx0301_date(m_real_local_jd(dat),
                          m_real_year(dat));
        return rb_str_append(strftimev(RSTRING_PTR(s), self, set_tmx),
                             iso8601_timediv(self, n));
    }
}
rfc3339([n=0]) → string click to toggle source

This method is equivalent to strftime('%FT%T'). The optional argument n is length of fractional seconds.

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').rfc3339(9)
                          #=> "2001-02-03T04:05:06.123456789+07:00"

static VALUE
dt_lite_rfc3339(int argc, VALUE *argv, VALUE self)
{
    return dt_lite_iso8601(argc, argv, self);
}
strftime([format='%FT%T%:z']) → string click to toggle source
Formats date according to the directives in the given format
string.
The directives begins with a percent (%Q( character.
Any text not listed as a directive will be passed through to the
output string.

The directive consists of a percent (%) character,
zero or more flags, optional minimum field width,
optional modifier and a conversion specifier
as follows.

  %<flags><width><modifier><conversion>

Flags:
  -  don't pad a numerical output.
  _  use spaces for padding.
  0  use zeros for padding.
  ^  upcase the result string.
  #  change case.
  :  use colons for %z.

The minimum field width specifies the minimum width.

The modifier is "E" and "O".
They are ignored.

Format directives:

  Date (Year, Month, Day):
    %Y - Year with century (can be negative, 4 digits at least)
            -0001, 0000, 1995, 2009, 14292, etc.
    %C - year / 100 (round down.  20 in 2009)
    %y - year % 100 (00..99)

    %m - Month of the year, zero-padded (01..12)
            %_m  blank-padded ( 1..12)
            %-m  no-padded (1..12)
    %B - The full month name (``January'')
            %^B  uppercased (``JANUARY'')
    %b - The abbreviated month name (``Jan'')
            %^b  uppercased (``JAN'')
    %h - Equivalent to %b

    %d - Day of the month, zero-padded (01..31)
            %-d  no-padded (1..31)
    %e - Day of the month, blank-padded ( 1..31)

    %j - Day of the year (001..366)

  Time (Hour, Minute, Second, Subsecond):
    %H - Hour of the day, 24-hour clock, zero-padded (00..23)
    %k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
    %I - Hour of the day, 12-hour clock, zero-padded (01..12)
    %l - Hour of the day, 12-hour clock, blank-padded ( 1..12)
    %P - Meridian indicator, lowercase (``am'' or ``pm'')
    %p - Meridian indicator, uppercase (``AM'' or ``PM'')

    %M - Minute of the hour (00..59)

    %S - Second of the minute (00..59)

    %L - Millisecond of the second (000..999)
    %N - Fractional seconds digits, default is 9 digits (nanosecond)
            %3N  millisecond (3 digits)   %15N femtosecond (15 digits)
            %6N  microsecond (6 digits)   %18N attosecond  (18 digits)
            %9N  nanosecond  (9 digits)   %21N zeptosecond (21 digits)
            %12N picosecond (12 digits)   %24N yoctosecond (24 digits)

  Time zone:
    %z - Time zone as hour and minute offset from UTC (e.g. +0900)
            %:z - hour and minute offset from UTC with a colon (e.g. +09:00)
            %::z - hour, minute and second offset from UTC (e.g. +09:00:00)
            %:::z - hour, minute and second offset from UTC
                                              (e.g. +09, +09:30, +09:30:30)
    %Z - Time zone abbreviation name or something similar information.

  Weekday:
    %A - The full weekday name (``Sunday'')
            %^A  uppercased (``SUNDAY'')
    %a - The abbreviated name (``Sun'')
            %^a  uppercased (``SUN'')
    %u - Day of the week (Monday is 1, 1..7)
    %w - Day of the week (Sunday is 0, 0..6)

  ISO 8601 week-based year and week number:
  The week 1 of YYYY starts with a Monday and includes YYYY-01-04.
  The days in the year before the first week are in the last week of
  the previous year.
    %G - The week-based year
    %g - The last 2 digits of the week-based year (00..99)
    %V - Week number of the week-based year (01..53)

  Week number:
  The week 1 of YYYY starts with a Sunday or Monday (according to %U
  or %W).  The days in the year before the first week are in week 0.
    %U - Week number of the year.  The week starts with Sunday.  (00..53)
    %W - Week number of the year.  The week starts with Monday.  (00..53)

  Seconds since the Unix Epoch:
    %s - Number of seconds since 1970-01-01 00:00:00 UTC.
    %Q - Number of milliseconds since 1970-01-01 00:00:00 UTC.

  Literal string:
    %n - Newline character (\n)
    %t - Tab character (\t)
    %% - Literal ``%'' character

  Combination:
    %c - date and time (%a %b %e %T %Y)
    %D - Date (%m/%d/%y)
    %F - The ISO 8601 date format (%Y-%m-%d)
    %v - VMS date (%e-%b-%Y)
    %x - Same as %D
    %X - Same as %T
    %r - 12-hour time (%I:%M:%S %p)
    %R - 24-hour time (%H:%M)
    %T - 24-hour time (%H:%M:%S)
    %+ - date(1) (%a %b %e %H:%M:%S %Z %Y)

This method is similar to strftime() function defined in ISO C and POSIX.
Several directives (%a, %A, %b, %B, %c, %p, %r, %x, %X, %E*, %O* and %Z)
are locale dependent in the function.
However this method is locale independent.
So, the result may differ even if a same format string is used in other
systems such as C.
It is good practice to avoid %x and %X because there are corresponding
locale independent representations, %D and %T.

Examples:

  d = DateTime.new(2007,11,19,8,37,48,"-06:00")
                            #=> #<DateTime: 2007-11-19T08:37:48-0600 ...>
  d.strftime("Printed on %m/%d/%Y")   #=> "Printed on 11/19/2007"
  d.strftime("at %I:%M%p")            #=> "at 08:37AM"

Various ISO 8601 formats:
  %Y%m%d           => 20071119                  Calendar date (basic)
  %F               => 2007-11-19                Calendar date (extended)
  %Y-%m            => 2007-11                   Calendar date, reduced accuracy, specific month
  %Y               => 2007                      Calendar date, reduced accuracy, specific year
  %C               => 20                        Calendar date, reduced accuracy, specific century
  %Y%j             => 2007323                   Ordinal date (basic)
  %Y-%j            => 2007-323                  Ordinal date (extended)
  %GW%V%u          => 2007W471                  Week date (basic)
  %G-W%V-%u        => 2007-W47-1                Week date (extended)
  %GW%V            => 2007W47                   Week date, reduced accuracy, specific week (basic)
  %G-W%V           => 2007-W47                  Week date, reduced accuracy, specific week (extended)
  %H%M%S           => 083748                    Local time (basic)
  %T               => 08:37:48                  Local time (extended)
  %H%M             => 0837                      Local time, reduced accuracy, specific minute (basic)
  %H:%M            => 08:37                     Local time, reduced accuracy, specific minute (extended)
  %H               => 08                        Local time, reduced accuracy, specific hour
  %H%M%S,%L        => 083748,000                Local time with decimal fraction, comma as decimal sign (basic)
  %T,%L            => 08:37:48,000              Local time with decimal fraction, comma as decimal sign (extended)
  %H%M%S.%L        => 083748.000                Local time with decimal fraction, full stop as decimal sign (basic)
  %T.%L            => 08:37:48.000              Local time with decimal fraction, full stop as decimal sign (extended)
  %H%M%S%z         => 083748-0600               Local time and the difference from UTC (basic)
  %T%:z            => 08:37:48-06:00            Local time and the difference from UTC (extended)
  %Y%m%dT%H%M%S%z  => 20071119T083748-0600      Date and time of day for calendar date (basic)
  %FT%T%:z         => 2007-11-19T08:37:48-06:00 Date and time of day for calendar date (extended)
  %Y%jT%H%M%S%z    => 2007323T083748-0600       Date and time of day for ordinal date (basic)
  %Y-%jT%T%:z      => 2007-323T08:37:48-06:00   Date and time of day for ordinal date (extended)
  %GW%V%uT%H%M%S%z => 2007W471T083748-0600      Date and time of day for week date (basic)
  %G-W%V-%uT%T%:z  => 2007-W47-1T08:37:48-06:00 Date and time of day for week date (extended)
  %Y%m%dT%H%M      => 20071119T0837             Calendar date and local time (basic)
  %FT%R            => 2007-11-19T08:37          Calendar date and local time (extended)
  %Y%jT%H%MZ       => 2007323T0837Z             Ordinal date and UTC of day (basic)
  %Y-%jT%RZ        => 2007-323T08:37Z           Ordinal date and UTC of day (extended)
  %GW%V%uT%H%M%z   => 2007W471T0837-0600        Week date and local time and difference from UTC (basic)
  %G-W%V-%uT%R%:z  => 2007-W47-1T08:37-06:00    Week date and local time and difference from UTC (extended)

See also strftime(3) and strptime.

static VALUE
dt_lite_strftime(int argc, VALUE *argv, VALUE self)
{
    return date_strftime_internal(argc, argv, self,
                                  "%Y-%m-%dT%H:%M:%S%:z", set_tmx);
}
to_date → date click to toggle source

Returns a Date object which denotes self.

static VALUE
datetime_to_date(VALUE self)
{
    get_d1a(self);

    if (simple_dat_p(adat)) {
        VALUE new = d_lite_s_alloc_simple(cDate);
        {
            get_d1b(new);
            bdat->s = adat->s;
            bdat->s.jd = m_local_jd(adat);
            return new;
        }
    }
    else {
        VALUE new = d_lite_s_alloc_simple(cDate);
        {
            get_d1b(new);
            copy_complex_to_simple(&bdat->s, &adat->c)
            bdat->s.jd = m_local_jd(adat);
            bdat->s.flags &= ~(HAVE_DF | HAVE_TIME | COMPLEX_DAT);
            return new;
        }
    }
}
to_datetime → self click to toggle source

Returns self.

static VALUE
datetime_to_datetime(VALUE self)
{
    return self;
}
to_json(*args) click to toggle source

Stores class name (DateTime) with Julian year y, month m, day d, hour H, minute M, second S, offset of and Day of Calendar Reform sg as JSON string

# File ext/json/lib/json/add/date_time.rb, line 45
def to_json(*args)
  as_json.to_json(*args)
end
to_s → string click to toggle source

Returns a string in an ISO 8601 format (This method doesn't use the expanded representations).

DateTime.new(2001,2,3,4,5,6,'-7').to_s
                         #=> "2001-02-03T04:05:06-07:00"

static VALUE
dt_lite_to_s(VALUE self)
{
    return strftimev("%Y-%m-%dT%H:%M:%S%:z", self, set_tmx);
}
to_time → time click to toggle source

Returns a Time object which denotes self.

static VALUE
datetime_to_time(VALUE self)
{
    volatile VALUE dup = dup_obj_with_new_offset(self, 0);
    {
        VALUE t;

        get_d1(dup);

        t = f_utc6(rb_cTime,
                   m_real_year(dat),
                   INT2FIX(m_mon(dat)),
                   INT2FIX(m_mday(dat)),
                   INT2FIX(m_hour(dat)),
                   INT2FIX(m_min(dat)),
                   f_add(INT2FIX(m_sec(dat)),
                         m_sf_in_sec(dat)));
        return f_getlocal(t);
    }
}
iso8601([n=0]) → string click to toggle source
xmlschema([n=0]) → string

This method is equivalent to strftime('%FT%T'). The optional argument n is length of fractional seconds.

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').iso8601(9)
                          #=> "2001-02-03T04:05:06.123456789+07:00"

static VALUE
dt_lite_iso8601(int argc, VALUE *argv, VALUE self)
{
    VALUE n;

    rb_scan_args(argc, argv, "01", &n);

    if (argc < 1)
        n = INT2FIX(0);

    return f_add(strftimev("%Y-%m-%d", self, set_tmx),
                 iso8601_timediv(self, n));
}


class Delegator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Delegator

This library provides three different ways to delegate method calls to an object. The easiest to use is SimpleDelegator. Pass an object to the constructor and all methods supported by the object will be delegated. This object can be changed later.

Going a step further, the top level DelegateClass method allows you to easily setup delegation through class inheritance. This is considerably more flexible and thus probably the most common use for this library.

Finally, if you need full control over the delegation scheme, you can inherit from the abstract class Delegator and customize as needed. (If you find yourself needing this control, have a look at Forwardable which is also in the standard library. It may suit your needs better.)

SimpleDelegator's implementation serves as a nice example if the use of Delegator:

class SimpleDelegator < Delegator
  def initialize(obj)
    super                  # pass obj to Delegator constructor, required
    @delegate_sd_obj = obj # store obj for future use
  end

  def __getobj__
    @delegate_sd_obj # return object we are delegating to, required
  end

  def __setobj__(obj)
    @delegate_sd_obj = obj # change delegation object,
                           # a feature we're providing
  end
end

Notes

Be advised, RDoc will not detect delegated methods.

In Files

  • lib/delegate.rb

Parent

BasicObject

Public Class Methods

new(obj) click to toggle source

Pass in the obj to delegate method calls to. All methods supported by obj will be delegated to.

# File lib/delegate.rb, line 62
def initialize(obj)
  __setobj__(obj)
end

Public Instance Methods

!() click to toggle source

Delegates ! to the __getobj__

# File lib/delegate.rb, line 136
def !
  !__getobj__
end
!=(obj) click to toggle source

Returns true if two objects are not considered of equal value.

# File lib/delegate.rb, line 128
def !=(obj)
  return false if obj.equal?(self)
  __getobj__ != obj
end
==(obj) click to toggle source

Returns true if two objects are considered of equal value.

# File lib/delegate.rb, line 120
def ==(obj)
  return true if obj.equal?(self)
  self.__getobj__ == obj
end
__getobj__() click to toggle source

This method must be overridden by subclasses and should return the object method calls are being delegated to.

# File lib/delegate.rb, line 144
def __getobj__
  raise NotImplementedError, "need to define `__getobj__'"
end
__setobj__(obj) click to toggle source

This method must be overridden by subclasses and change the object delegate to obj.

# File lib/delegate.rb, line 152
def __setobj__(obj)
  raise NotImplementedError, "need to define `__setobj__'"
end
freeze() click to toggle source

Freeze both the object returned by __getobj__ and self.

# File lib/delegate.rb, line 214
marshal_dump() click to toggle source

Serialization support for the object returned by __getobj__.

# File lib/delegate.rb, line 159
def marshal_dump
  ivars = instance_variables.reject {|var| /\A@delegate_/ =~ var}
  [
    :__v2__,
    ivars, ivars.map{|var| instance_variable_get(var)},
    __getobj__
  ]
end
marshal_load(data) click to toggle source

Reinitializes delegation from a serialized object.

# File lib/delegate.rb, line 171
def marshal_load(data)
  version, vars, values, obj = data
  if version == :__v2__
    vars.each_with_index{|var, i| instance_variable_set(var, values[i])}
    __setobj__(obj)
  else
    __setobj__(data)
  end
end
method_missing(m, *args, &block) click to toggle source

Handles the magic of delegation through __getobj__.

# File lib/delegate.rb, line 69
def method_missing(m, *args, &block)
  target = self.__getobj__
  begin
    target.respond_to?(m) ? target.__send__(m, *args, &block) : super(m, *args, &block)
  ensure
    $@.delete_if {|t| %r\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:" =~ t} if $@
  end
end
methods(all=true) click to toggle source

Returns the methods available to this delegate object as the union of this object's and __getobj__ methods.

# File lib/delegate.rb, line 95
def methods(all=true)
  __getobj__.methods(all) | super
end
protected_methods(all=true) click to toggle source

Returns the methods available to this delegate object as the union of this object's and __getobj__ protected methods.

# File lib/delegate.rb, line 111
def protected_methods(all=true)
  __getobj__.protected_methods(all) | super
end
public_methods(all=true) click to toggle source

Returns the methods available to this delegate object as the union of this object's and __getobj__ public methods.

# File lib/delegate.rb, line 103
def public_methods(all=true)
  __getobj__.public_methods(all) | super
end
respond_to_missing?(m, include_private) click to toggle source

Checks for a method provided by this the delegate object by forwarding the call through __getobj__.

# File lib/delegate.rb, line 82
def respond_to_missing?(m, include_private)
  r = self.__getobj__.respond_to?(m, include_private)
  if r && include_private && !self.__getobj__.respond_to?(m, false)
    warn "#{caller(3)[0]}: delegator does not forward private method \##{m}"
    return false
  end
  r
end
taint() click to toggle source

Taint both the object returned by __getobj__ and self.

# File lib/delegate.rb, line 204
trust() click to toggle source

Trust both the object returned by __getobj__ and self.

# File lib/delegate.rb, line 194
untaint() click to toggle source

Untaint both the object returned by __getobj__ and self.

# File lib/delegate.rb, line 209
untrust() click to toggle source

Untrust both the object returned by __getobj__ and self.

# File lib/delegate.rb, line 199


module Digest - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Digest

This module provides a framework for message digest libraries.

You may want to look at OpenSSL::Digest as it supports support more algorithms.

A cryptographic hash function is a procedure that takes data and return a fixed bit string : the hash value, also known as digest. Hash functions are also called one-way functions, it is easy to compute a digest from a message, but it is infeasible to generate a message from a digest.

Example

require 'digest'

# Compute a complete digest
sha256 = Digest::SHA256.new
digest = sha256.digest message

# Compute digest by chunks
sha256 = Digest::SHA256.new
sha256.update message1
sha256 << message2 # << is an alias for update

digest = sha256.digest

Digest algorithms

Different digest algorithms (or hash functions) are available :

HMAC

See FIPS PUB 198 The Keyed-Hash Message Authentication Code (HMAC)

RIPEMD-160

(as Digest::RMD160) see homes.esat.kuleuven.be/~bosselae/ripemd160.html

SHA1

See FIPS 180 Secure Hash Standard

SHA2 family

See FIPS 180 Secure Hash Standard which defines the following algorithms:

  • SHA512

  • SHA384

  • SHA256

The latest versions of the FIPS publications can be found here: csrc.nist.gov/publications/PubsFIPS.html

Additionally Digest::BubbleBabble encodes a digest as a sequence of consonants and vowels which is more recognizable and comparable than a hexadecimal digest. See en.wikipedia.org/wiki/Bubblebabble

In Files

  • ext/digest/digest.c
  • ext/digest/lib/digest/hmac.rb
  • ext/digest/lib/digest.rb
  • ext/digest/md5/md5init.c
  • ext/digest/rmd160/rmd160init.c
  • ext/digest/sha1/sha1init.c

Public Class Methods

hexencode(string) → hexencoded_string click to toggle source

Generates a hex-encoded version of a given string.

static VALUE
rb_digest_s_hexencode(VALUE klass, VALUE str)
{
    return hexencode_str_new(str);
}


class Digest::Base - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Digest::Base

This abstract class provides a common interface to message digest implementation classes written in C.

In Files

  • ext/digest/digest.c

Parent

Digest::Class


class Digest::Class - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Digest::Class

This module stands as a base class for digest implementation classes.

In Files

  • ext/digest/digest.c
  • ext/digest/lib/digest.rb

Parent

Object

Included Modules

  • Digest::Instance

Public Class Methods

base64digest(str, *args) click to toggle source

Returns the base64 encoded hash value of a given string. The return value is properly padded with '=' and contains no line feeds.

# File ext/digest/lib/digest.rb, line 35
def self.base64digest(str, *args)
  [digest(str, *args)].pack('m0')
end
Digest::Class.digest(string, *parameters) → hash_string click to toggle source

Returns the hash value of a given string. This is equivalent to Digest::Instance#new.digest(string), where extra parameters, if any, are passed through to the constructor and the string is passed to digest().

static VALUE
rb_digest_class_s_digest(int argc, VALUE *argv, VALUE klass)
{
    VALUE str;
    volatile VALUE obj;

    if (argc < 1) {
        rb_raise(rb_eArgError, "no data given");
    }

    str = *argv++;
    argc--;

    StringValue(str);

    obj = rb_obj_alloc(klass);
    rb_obj_call_init(obj, argc, argv);

    return rb_funcall(obj, id_digest, 1, str);
}
file(name) click to toggle source

creates a digest object and reads a given file, name.

p Digest::SHA256.file("X11R6.8.2-src.tar.bz2").hexdigest
# => "f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534"

# File ext/digest/lib/digest.rb, line 28
def self.file(name)
  new.file(name)
end
Digest::Class.hexdigest(string[, ...]) → hash_string click to toggle source

Returns the hex-encoded hash value of a given string. This is almost equivalent to Digest.hexencode(Digest::Instance#new.digest(string)).

static VALUE
rb_digest_class_s_hexdigest(int argc, VALUE *argv, VALUE klass)
{
    return hexencode_str_new(rb_funcall2(klass, id_digest, argc, argv));
}


class Digest::HMAC - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Digest::HMAC

digest/hmac.rb

An experimental implementation of HMAC keyed-hashing algorithm

Overview

CAUTION: Use of this library is discouraged, because this implementation was meant to be experimental but somehow got into the 1.9 series without being noticed. Please use OpenSSL::HMAC in the “openssl” library instead.

Examples

require 'digest/hmac'

# one-liner example
puts Digest::HMAC.hexdigest("data", "hash key", Digest::SHA1)

# rather longer one
hmac = Digest::HMAC.new("foo", Digest::RMD160)

buf = ""
while stream.read(16384, buf)
  hmac.update(buf)
end

puts hmac.bubblebabble

In Files

  • ext/digest/lib/digest/hmac.rb

Parent

Digest::Class

Public Class Methods

new(key, digester) click to toggle source

Creates a Digest::HMAC instance.

# File ext/digest/lib/digest/hmac.rb, line 50
def initialize(key, digester)
  @md = digester.new

  block_len = @md.block_length

  if key.bytesize > block_len
    key = @md.digest(key)
  end

  ipad = Array.new(block_len, 0x36)
  opad = Array.new(block_len, 0x5c)

  key.bytes.each_with_index { |c, i|
    ipad[i] ^= c
    opad[i] ^= c
  }

  @key = key.freeze
  @ipad = ipad.pack('C*').freeze
  @opad = opad.pack('C*').freeze
  @md.update(@ipad)
end

Public Instance Methods

<<(text) click to toggle source
Alias for: update
block_length → Integer click to toggle source

Returns the block length in bytes of the hmac.

# File ext/digest/lib/digest/hmac.rb, line 118
def block_length
  @md.block_length
end
digest_length → Integer click to toggle source

Returns the length in bytes of the hash value of the digest.

# File ext/digest/lib/digest/hmac.rb, line 110
def digest_length
  @md.digest_length
end
inspect → string click to toggle source

Creates a printable version of the hmac object.

# File ext/digest/lib/digest/hmac.rb, line 126
def inspect
  sprintf('#<%s: key=%s, digest=%s>', self.class.name, @key.inspect, @md.inspect.sub(/^\#<(.*)>$/) { $1 });
end
reset → hmac click to toggle source

Resets the hmac to the initial state and returns self.

# File ext/digest/lib/digest/hmac.rb, line 92
def reset
  @md.reset
  @md.update(@ipad)
  self
end
update(string) → hmac click to toggle source
hmac << string → hmac

Updates the hmac using a given string and returns self.

# File ext/digest/lib/digest/hmac.rb, line 82
def update(text)
  @md.update(text)
  self
end
Also aliased as: <<


module Digest::Instance - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Digest::Instance

This module provides instance methods for a digest implementation object to calculate message digest values.

In Files

  • ext/digest/digest.c
  • ext/digest/lib/digest.rb

Public Instance Methods

update(string) → digest_obj click to toggle source
digest_obj << string → digest_obj

Updates the digest using a given string and returns self.

The update() method and the left-shift operator are overridden by each implementation subclass. (One should be an alias for the other)

static VALUE
rb_digest_instance_update(VALUE self, VALUE str)
{
    rb_digest_instance_method_unimpl(self, "update");

    UNREACHABLE;
}
digest_obj == another_digest_obj → boolean click to toggle source
digest_obj == string → boolean

If a string is given, checks whether it is equal to the hex-encoded hash value of the digest object. If another digest instance is given, checks whether they have the same hash value. Otherwise returns false.

static VALUE
rb_digest_instance_equal(VALUE self, VALUE other)
{
    VALUE str1, str2;

    if (rb_obj_is_kind_of(other, rb_mDigest_Instance) == Qtrue) {
        str1 = rb_digest_instance_digest(0, 0, self);
        str2 = rb_digest_instance_digest(0, 0, other);
    } else {
        str1 = rb_digest_instance_to_s(self);
        str2 = rb_check_string_type(other);
        if (NIL_P(str2)) return Qfalse;
    }

    /* never blindly assume that subclass methods return strings */
    StringValue(str1);
    StringValue(str2);

    if (RSTRING_LEN(str1) == RSTRING_LEN(str2) &&
        rb_str_cmp(str1, str2) == 0) {
        return Qtrue;
    }
    return Qfalse;
}
base64digest(str = nil) click to toggle source

If none is given, returns the resulting hash value of the digest in a base64 encoded form, keeping the digest's state.

If a string is given, returns the hash value for the given string in a base64 encoded form, resetting the digest to the initial state before and after the process.

In either case, the return value is properly padded with '=' and contains no line feeds.

# File ext/digest/lib/digest.rb, line 62
def base64digest(str = nil)
  [str ? digest(str) : digest].pack('m0')
end
base64digest!() click to toggle source

Returns the resulting hash value and resets the digest to the initial state.

# File ext/digest/lib/digest.rb, line 68
def base64digest!
  [digest!].pack('m0')
end
block_length → integer click to toggle source

Returns the block length of the digest.

This method is overridden by each implementation subclass.

static VALUE
rb_digest_instance_block_length(VALUE self)
{
    rb_digest_instance_method_unimpl(self, "block_length");

    UNREACHABLE;
}
digest → string click to toggle source
digest(string) → string

If none is given, returns the resulting hash value of the digest, keeping the digest's state.

If a string is given, returns the hash value for the given string, resetting the digest to the initial state before and after the process.

static VALUE
rb_digest_instance_digest(int argc, VALUE *argv, VALUE self)
{
    VALUE str, value;

    if (rb_scan_args(argc, argv, "01", &str) > 0) {
        rb_funcall(self, id_reset, 0);
        rb_funcall(self, id_update, 1, str);
        value = rb_funcall(self, id_finish, 0);
        rb_funcall(self, id_reset, 0);
    } else {
        value = rb_funcall(rb_obj_clone(self), id_finish, 0);
    }

    return value;
}
digest! → string click to toggle source

Returns the resulting hash value and resets the digest to the initial state.

static VALUE
rb_digest_instance_digest_bang(VALUE self)
{
    VALUE value = rb_funcall(self, id_finish, 0);
    rb_funcall(self, id_reset, 0);

    return value;
}
digest_length → integer click to toggle source

Returns the length of the hash value of the digest.

This method should be overridden by each implementation subclass. If not, digest_obj.digest().length() is returned.

static VALUE
rb_digest_instance_digest_length(VALUE self)
{
    /* subclasses really should redefine this method */
    VALUE digest = rb_digest_instance_digest(0, 0, self);

    /* never blindly assume that #digest() returns a string */
    StringValue(digest);
    return INT2NUM(RSTRING_LEN(digest));
}
file(name) click to toggle source

updates the digest with the contents of a given file name and returns self.

# File ext/digest/lib/digest.rb, line 43
def file(name)
  File.open(name, "rb") {|f|
    buf = ""
    while f.read(16384, buf)
      update buf
    end
  }
  self
end
hexdigest → string click to toggle source
hexdigest(string) → string

If none is given, returns the resulting hash value of the digest in a hex-encoded form, keeping the digest's state.

If a string is given, returns the hash value for the given string in a hex-encoded form, resetting the digest to the initial state before and after the process.

static VALUE
rb_digest_instance_hexdigest(int argc, VALUE *argv, VALUE self)
{
    VALUE str, value;

    if (rb_scan_args(argc, argv, "01", &str) > 0) {
        rb_funcall(self, id_reset, 0);
        rb_funcall(self, id_update, 1, str);
        value = rb_funcall(self, id_finish, 0);
        rb_funcall(self, id_reset, 0);
    } else {
        value = rb_funcall(rb_obj_clone(self), id_finish, 0);
    }

    return hexencode_str_new(value);
}
hexdigest! → string click to toggle source

Returns the resulting hash value in a hex-encoded form and resets the digest to the initial state.

static VALUE
rb_digest_instance_hexdigest_bang(VALUE self)
{
    VALUE value = rb_funcall(self, id_finish, 0);
    rb_funcall(self, id_reset, 0);

    return hexencode_str_new(value);
}
inspect → string click to toggle source

Creates a printable version of the digest object.

static VALUE
rb_digest_instance_inspect(VALUE self)
{
    VALUE str;
    size_t digest_len = 32;     /* about this size at least */
    const char *cname;

    cname = rb_obj_classname(self);

    /* #<Digest::ClassName: xxxxx...xxxx> */
    str = rb_str_buf_new(2 + strlen(cname) + 2 + digest_len * 2 + 1);
    rb_str_buf_cat2(str, "#<");
    rb_str_buf_cat2(str, cname);
    rb_str_buf_cat2(str, ": ");
    rb_str_buf_append(str, rb_digest_instance_hexdigest(0, 0, self));
    rb_str_buf_cat2(str, ">");
    return str;
}
length → integer click to toggle source
size → integer

Returns digest_obj.digest_length().

static VALUE
rb_digest_instance_length(VALUE self)
{
    return rb_funcall(self, id_digest_length, 0);
}
new → another_digest_obj click to toggle source

Returns a new, initialized copy of the digest object. Equivalent to digest_obj.clone().reset().

static VALUE
rb_digest_instance_new(VALUE self)
{
    VALUE clone = rb_obj_clone(self);
    rb_funcall(clone, id_reset, 0);
    return clone;
}
reset → digest_obj click to toggle source

Resets the digest to the initial state and returns self.

This method is overridden by each implementation subclass.

static VALUE
rb_digest_instance_reset(VALUE self)
{
    rb_digest_instance_method_unimpl(self, "reset");

    UNREACHABLE;
}
length → integer click to toggle source
size → integer

Returns digest_obj.digest_length().

static VALUE
rb_digest_instance_length(VALUE self)
{
    return rb_funcall(self, id_digest_length, 0);
}
to_s → string click to toggle source

Returns digest_obj.hexdigest().

static VALUE
rb_digest_instance_to_s(VALUE self)
{
    return rb_funcall(self, id_hexdigest, 0);
}
update(string) → digest_obj click to toggle source
digest_obj << string → digest_obj

Updates the digest using a given string and returns self.

The update() method and the left-shift operator are overridden by each implementation subclass. (One should be an alias for the other)

static VALUE
rb_digest_instance_update(VALUE self, VALUE str)
{
    rb_digest_instance_method_unimpl(self, "update");

    UNREACHABLE;
}


class Digest::MD5 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Digest::MD5

In Files

  • ext/digest/digest.c

Parent

cDigest_Base


class Digest::RMD160 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Digest::RMD160

In Files

  • ext/digest/digest.c

Parent

cDigest_Base


class Digest::SHA1 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Digest::SHA1

In Files

  • ext/digest/digest.c

Parent

cDigest_Base


class Dir - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Dir

In Files

  • lib/tmpdir.rb

Parent

Object

Public Class Methods

mktmpdir(prefix_suffix=nil, *rest) { |path| ... } click to toggle source

::mktmpdir creates a temporary directory.

The directory is created with 0700 permission. Application should not change the permission to make the temporary directory accesible from other users.

The prefix and suffix of the name of the directory is specified by the optional first argument, prefix_suffix.

  • If it is not specified or nil, “d” is used as the prefix and no suffix is used.

  • If it is a string, it is used as the prefix and no suffix is used.

  • If it is an array, first element is used as the prefix and second element is used as a suffix.

Dir.mktmpdir {|dir| dir is ".../d..." }
Dir.mktmpdir("foo") {|dir| dir is ".../foo..." }
Dir.mktmpdir(["foo", "bar"]) {|dir| dir is ".../foo...bar" }

The directory is created under ::tmpdir or the optional second argument tmpdir if non-nil value is given.

Dir.mktmpdir {|dir| dir is "#{Dir.tmpdir}/d..." }
Dir.mktmpdir(nil, "/var/tmp") {|dir| dir is "/var/tmp/d..." }

If a block is given, it is yielded with the path of the directory. The directory and its contents are removed using FileUtils.remove_entry before ::mktmpdir returns. The value of the block is returned.

Dir.mktmpdir {|dir|
  # use the directory...
  open("#{dir}/foo", "w") { ... }
}

If a block is not given, The path of the directory is returned. In this case, ::mktmpdir doesn't remove the directory.

dir = Dir.mktmpdir
begin
  # use the directory...
  open("#{dir}/foo", "w") { ... }
ensure
  # remove the directory.
  FileUtils.remove_entry dir
end
# File lib/tmpdir.rb, line 84
def Dir.mktmpdir(prefix_suffix=nil, *rest)
  path = Tmpname.create(prefix_suffix || "d", *rest) {|n| mkdir(n, 0700)}
  if block_given?
    begin
      yield path
    ensure
      stat = File.stat(File.dirname(path))
      if stat.world_writable? and !stat.sticky?
        raise ArgumentError, "parent directory is world writable but not sticky"
      end
      FileUtils.remove_entry path
    end
  else
    path
  end
end
tmpdir() click to toggle source

Returns the operating system's temporary file path.

# File lib/tmpdir.rb, line 20
def Dir::tmpdir
  if $SAFE > 0
    tmp = @@systmpdir
  else
    tmp = nil
    for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'], @@systmpdir, '/tmp', '.']
      next if !dir
      dir = File.expand_path(dir)
      if stat = File.stat(dir) and stat.directory? and stat.writable? and
          (!stat.world_writable? or stat.sticky?)
        tmp = dir
        break
      end rescue nil
    end
    raise ArgumentError, "could not find a temporary directory" if !tmp
    tmp
  end
end


module ENV - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module ENV

In Files

  • lib/pp.rb

Public Class Methods

pretty_print(q) click to toggle source
# File lib/pp.rb, line 352
def pretty_print(q)
  h = {}
  ENV.keys.sort.each {|k|
    h[k] = ENV[k]
  }
  q.pp_hash h
end


class ERB - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class ERB

ERB – Ruby Templating

Introduction

ERB provides an easy to use but powerful templating system for Ruby. Using ERB, actual Ruby code can be added to any plain text document for the purposes of generating document information details and/or flow control.

A very simple example is this:

require 'erb'

x = 42
template = ERB.new <<-EOF
  The value of x is: <%= x %>
EOF
puts template.result(binding)

Prints: The value of x is: 42

More complex examples are given below.

Recognized Tags

ERB recognizes certain tags in the provided template and converts them based on the rules below:

<% Ruby code -- inline with output %>
<%= Ruby expression -- replace with result %>
<%# comment -- ignored -- useful in testing %>
% a line of Ruby code -- treated as <% line %> (optional -- see ERB.new)
%% replaced with % if first thing on a line and % processing is used
<%% or %%> -- replace with <% or %> respectively

All other text is passed through ERB filtering unchanged.

Options

There are several settings you can change when you use ERB:

  • the nature of the tags that are recognized;

  • the value of $SAFE under which the template is run;

  • the binding used to resolve local variables in the template.

See the ::new and #result methods for more detail.

Character encodings

ERB (or ruby code generated by ERB) returns a string in the same character encoding as the input string. When the input string has a magic comment, however, it returns a string in the encoding specified by the magic comment.

# -*- coding: UTF-8 -*-
require 'erb'

template = ERB.new <<EOF
<%#-*- coding: Big5 -*-%>
  \_\_ENCODING\_\_ is <%= \_\_ENCODING\_\_ %>.
EOF
puts template.result

Prints: __ENCODING__ is Big5.

Examples

Plain Text

ERB is useful for any generic templating situation. Note that in this example, we use the convenient “% at start of line” tag, and we quote the template literally with %q{...} to avoid trouble with the backslash.

require "erb"

# Create template.
template = %q{
  From:  James Edward Gray II <james@grayproductions.net>
  To:  <%= to %>
  Subject:  Addressing Needs

  <%= to[/\w+/] %>:

  Just wanted to send a quick note assuring that your needs are being
  addressed.

  I want you to know that my team will keep working on the issues,
  especially:

  <%# ignore numerous minor requests -- focus on priorities %>
  % priorities.each do |priority|
    * <%= priority %>
  % end

  Thanks for your patience.

  James Edward Gray II
}.gsub(/^  /, '')

message = ERB.new(template, 0, "%<>")

# Set up template data.
to = "Community Spokesman <spokesman@ruby_community.org>"
priorities = [ "Run Ruby Quiz",
               "Document Modules",
               "Answer Questions on Ruby Talk" ]

# Produce result.
email = message.result
puts email

Generates:

From:  James Edward Gray II <james@grayproductions.net>
To:  Community Spokesman <spokesman@ruby_community.org>
Subject:  Addressing Needs

Community:

Just wanted to send a quick note assuring that your needs are being addressed.

I want you to know that my team will keep working on the issues, especially:

    * Run Ruby Quiz
    * Document Modules
    * Answer Questions on Ruby Talk

Thanks for your patience.

James Edward Gray II

Ruby in HTML

ERB is often used in .rhtml files (HTML with embedded Ruby). Notice the need in this example to provide a special binding when the template is run, so that the instance variables in the Product object can be resolved.

require "erb"

# Build template data class.
class Product
  def initialize( code, name, desc, cost )
    @code = code
    @name = name
    @desc = desc
    @cost = cost

    @features = [ ]
  end

  def add_feature( feature )
    @features << feature
  end

  # Support templating of member data.
  def get_binding
    binding
  end

  # ...
end

# Create template.
template = %{
  <html>
    <head><title>Ruby Toys -- <%= @name %></title></head>
    <body>

      <h1><%= @name %> (<%= @code %>)</h1>
      <p><%= @desc %></p>

      <ul>
        <% @features.each do |f| %>
          <li><b><%= f %></b></li>
        <% end %>
      </ul>

      <p>
        <% if @cost < 10 %>
          <b>Only <%= @cost %>!!!</b>
        <% else %>
           Call for a price, today!
        <% end %>
      </p>

    </body>
  </html>
}.gsub(/^  /, '')

rhtml = ERB.new(template)

# Set up template data.
toy = Product.new( "TZ-1002",
                   "Rubysapien",
                   "Geek's Best Friend!  Responds to Ruby commands...",
                   999.95 )
toy.add_feature("Listens for verbal commands in the Ruby language!")
toy.add_feature("Ignores Perl, Java, and all C variants.")
toy.add_feature("Karate-Chop Action!!!")
toy.add_feature("Matz signature on left leg.")
toy.add_feature("Gem studded eyes... Rubies, of course!")

# Produce result.
rhtml.run(toy.get_binding)

Generates (some blank lines removed):

<html>
  <head><title>Ruby Toys -- Rubysapien</title></head>
  <body>

    <h1>Rubysapien (TZ-1002)</h1>
    <p>Geek's Best Friend!  Responds to Ruby commands...</p>

    <ul>
        <li><b>Listens for verbal commands in the Ruby language!</b></li>
        <li><b>Ignores Perl, Java, and all C variants.</b></li>
        <li><b>Karate-Chop Action!!!</b></li>
        <li><b>Matz signature on left leg.</b></li>
        <li><b>Gem studded eyes... Rubies, of course!</b></li>
    </ul>

    <p>
         Call for a price, today!
    </p>

  </body>
</html>

Notes

There are a variety of templating solutions available in various Ruby projects:

  • ERB's big brother, eRuby, works the same but is written in C for speed;

  • Amrita (smart at producing HTML/XML);

  • cs/Template (written in C for speed);

  • RDoc, distributed with Ruby, uses its own template engine, which can be reused elsewhere;

  • and others; search the RAA.

Rails, the web application framework, uses ERB to create views.

In Files

  • lib/erb.rb

Parent

Object

Attributes

filename[RW]

The optional filename argument passed to Kernel#eval when the ERB code is run

src[R]

The Ruby code generated by ERB

Public Class Methods

new(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout') click to toggle source

Constructs a new ERB object with the template specified in str.

An ERB object works by building a chunk of Ruby code that will output the completed template when run. If safe_level is set to a non-nil value, ERB code will be run in a separate thread with $SAFE set to the provided level.

If trim_mode is passed a String containing one or more of the following modifiers, ERB will adjust its code generation as listed:

%  enables Ruby code processing for lines beginning with %
<> omit newline for lines starting with <% and ending in %>
>  omit newline for lines ending in %>
-  omit blank lines ending in -%>

eoutvar can be used to set the name of the variable ERB will build up its output in. This is useful when you need to run multiple ERB templates through the same binding and/or when you want to control where output ends up. Pass the name of the variable to be used inside a String.

Example

require "erb"

# build data class
class Listings
  PRODUCT = { :name => "Chicken Fried Steak",
              :desc => "A well messages pattie, breaded and fried.",
              :cost => 9.95 }

  attr_reader :product, :price

  def initialize( product = "", price = "" )
    @product = product
    @price = price
  end

  def build
    b = binding
    # create and run templates, filling member data variables
    ERB.new(<<-'END_PRODUCT'.gsub(/^\s+/, ""), 0, "", "@product").result b
      <%= PRODUCT[:name] %>
      <%= PRODUCT[:desc] %>
    END_PRODUCT
    ERB.new(<<-'END_PRICE'.gsub(/^\s+/, ""), 0, "", "@price").result b
      <%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %>
      <%= PRODUCT[:desc] %>
    END_PRICE
  end
end

# setup template data
listings = Listings.new
listings.build

puts listings.product + "\n" + listings.price

Generates

Chicken Fried Steak
A well messages pattie, breaded and fried.

Chicken Fried Steak -- 9.95
A well messages pattie, breaded and fried.
# File lib/erb.rb, line 794
def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout')
  @safe_level = safe_level
  compiler = make_compiler(trim_mode)
  set_eoutvar(compiler, eoutvar)
  @src, @enc = *compiler.compile(str)
  @filename = nil
end
version() click to toggle source

Returns revision information for the erb.rb module.

# File lib/erb.rb, line 262
def self.version
  "erb.rb [2.1.0 #{ERB::Revision.split[1]}]"
end

Public Instance Methods

def_class(superklass=Object, methodname='result') click to toggle source

Define unnamed class which has methodname as instance method, and return it.

example:

class MyClass_
  def initialize(arg1, arg2)
    @arg1 = arg1;  @arg2 = arg2
  end
end
filename = 'example.rhtml'  # @arg1 and @arg2 are used in example.rhtml
erb = ERB.new(File.read(filename))
erb.filename = filename
MyClass = erb.def_class(MyClass_, 'render()')
print MyClass.new('foo', 123).render()

# File lib/erb.rb, line 905
def def_class(superklass=Object, methodname='result')
  cls = Class.new(superklass)
  def_method(cls, methodname, @filename || '(ERB)')
  cls
end
def_method(mod, methodname, fname='(ERB)') click to toggle source

Define methodname as instance method of mod from compiled ruby source.

example:

filename = 'example.rhtml'   # 'arg1' and 'arg2' are used in example.rhtml
erb = ERB.new(File.read(filename))
erb.def_method(MyClass, 'render(arg1, arg2)', filename)
print MyClass.new.render('foo', 123)
# File lib/erb.rb, line 868
def def_method(mod, methodname, fname='(ERB)')
  src = self.src
  magic_comment = "#coding:#{@enc}\n"
  mod.module_eval do
    eval(magic_comment + "def #{methodname}\n" + src + "\nend\n", binding, fname, -2)
  end
end
def_module(methodname='erb') click to toggle source

Create unnamed module, define methodname as instance method of it, and return it.

example:

filename = 'example.rhtml'   # 'arg1' and 'arg2' are used in example.rhtml
erb = ERB.new(File.read(filename))
erb.filename = filename
MyModule = erb.def_module('render(arg1, arg2)')
class MyClass
  include MyModule
end

# File lib/erb.rb, line 886
def def_module(methodname='erb')
  mod = Module.new
  def_method(mod, methodname, @filename || '(ERB)')
  mod
end
make_compiler(trim_mode) click to toggle source

Creates a new compiler for ERB. See ERB::Compiler.new for details

# File lib/erb.rb, line 805
def make_compiler(trim_mode)
  ERB::Compiler.new(trim_mode)
end
result(b=new_toplevel) click to toggle source

Executes the generated ERB code to produce a completed template, returning the results of that code. (See ::new for details on how this process can be affected by safe_level.)

b accepts a Binding object which is used to set the context of code evaluation.

# File lib/erb.rb, line 841
def result(b=new_toplevel)
  if @safe_level
    proc {
      $SAFE = @safe_level
      eval(@src, b, (@filename || '(erb)'), 0)
    }.call
  else
    eval(@src, b, (@filename || '(erb)'), 0)
  end
end
run(b=new_toplevel) click to toggle source

Generate results and print them. (see #result)

# File lib/erb.rb, line 829
def run(b=new_toplevel)
  print self.result(b)
end
set_eoutvar(compiler, eoutvar = '_erbout') click to toggle source

Can be used to set eoutvar as described in ::new. It's probably easier to just use the constructor though, since calling this method requires the setup of an ERB compiler object.

# File lib/erb.rb, line 821
def set_eoutvar(compiler, eoutvar = '_erbout')
  compiler.put_cmd = "#{eoutvar}.concat"
  compiler.insert_cmd = "#{eoutvar}.concat"
  compiler.pre_cmd = ["#{eoutvar} = ''"]
  compiler.post_cmd = ["#{eoutvar}.force_encoding(__ENCODING__)"]
end


module ERB::DefMethod - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module ERB::DefMethod

Utility module to define eRuby script as instance method.

Example

example.rhtml:

<% for item in @items %>
<b><%= item %></b>
<% end %>

example.rb:

require 'erb'
class MyClass
  extend ERB::DefMethod
  def_erb_method('render()', 'example.rhtml')
  def initialize(items)
    @items = items
  end
end
print MyClass.new([10,20,30]).render()

result:

<b>10</b>

<b>20</b>

<b>30</b>

In Files

  • lib/erb.rb

Public Class Methods

def_erb_method(methodname, erb_or_fname) click to toggle source

define methodname as instance method of current module, using ERB object or eRuby file

# File lib/erb.rb, line 995
def def_erb_method(methodname, erb_or_fname)
  if erb_or_fname.kind_of? String
    fname = erb_or_fname
    erb = ERB.new(File.read(fname))
    erb.def_method(self, methodname, fname)
  else
    erb = erb_or_fname
    erb.def_method(self, methodname, erb.filename || '(ERB)')
  end
end


module ERB::Util - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module ERB::Util

A utility module for conversion routines, often handy in HTML generation.

In Files

  • lib/erb.rb

Public Class Methods

h(s) click to toggle source
Alias for: html_escape
html_escape(s) click to toggle source

A utility method for escaping HTML tag characters in s.

require "erb"
include ERB::Util

puts html_escape("is a > 0 & a < 10?")

Generates

is a &gt; 0 &amp; a &lt; 10?
# File lib/erb.rb, line 930
def html_escape(s)
  CGI.escapeHTML(s.to_s)
end
Also aliased as: h
u(s) click to toggle source
Alias for: url_encode
url_encode(s) click to toggle source

A utility method for encoding the String s as a URL.

require "erb"
include ERB::Util

puts url_encode("Programming Ruby:  The Pragmatic Programmer's Guide")

Generates

Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide
# File lib/erb.rb, line 949
def url_encode(s)
  s.to_s.dup.force_encoding("ASCII-8BIT").gsub(/[^a-zA-Z0-9_\-.]/) {
    sprintf("%%%02X", $&.unpack("C")[0])
  }
end
Also aliased as: u


module English - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module English

Include the English library file in a Ruby script, and you can reference the global variables such as VAR{$_} using less cryptic names, listed in the following table.% vref{tab:english}.

Without 'English':

$\ = ' -- '
"waterbuffalo" =~ /buff/
print $", $', $$, "\n"

With English:

require "English"

$OUTPUT_FIELD_SEPARATOR = ' -- '
"waterbuffalo" =~ /buff/
print $LOADED_FEATURES, $POSTMATCH, $PID, "\n"

Below is a full list of descriptive aliases and their associated global variable:

$ERROR_INFO

$!

$ERROR_POSITION

$@

$FS

$;

$FIELD_SEPARATOR

$;

$OFS

$,

$OUTPUT_FIELD_SEPARATOR

$,

$RS

$/

$INPUT_RECORD_SEPARATOR

$/

$ORS

$\

$OUTPUT_RECORD_SEPARATOR

$\

$INPUT_LINE_NUMBER

$.

$NR

$.

$LAST_READ_LINE

$_

$DEFAULT_OUTPUT

$>

$DEFAULT_INPUT

$<

$PID

$$

$PROCESS_ID

$$

$CHILD_STATUS

$?

$LAST_MATCH_INFO

$~

$IGNORECASE

$=

$ARGV

$*

$MATCH

$&

$PREMATCH

$`

$POSTMATCH

$'

$LAST_PAREN_MATCH

$+

In Files

  • lib/English.rb


module Enumerable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Enumerable

In Files

  • lib/set.rb

Public Instance Methods

to_set(klass = Set, *args, &block) click to toggle source

Makes a set from the enumerable object with given arguments. Needs to +require “set”+ to use this method.

# File lib/set.rb, line 635
def to_set(klass = Set, *args, &block)
  klass.new(self, *args, &block)
end


module Errno - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Errno

System call error module used by webrick for cross platform compatability.

EPROTO

protocol error

ECONNRESET

remote host reset the connection request

ECONNABORTED

Client sent TCP reset (RST) before server has accepted the connection requested by client.

In Files

  • lib/webrick/compat.rb


class Errno::ECONNABORTED - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Errno::ECONNABORTED

Client sent TCP reset (RST) before server has accepted the connection requested by client.

In Files

  • lib/webrick/compat.rb

Parent

SystemCallError


class Errno::ECONNRESET - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Errno::ECONNRESET

Remote host reset the connection request.

In Files

  • lib/webrick/compat.rb

Parent

SystemCallError


class Errno::EPROTO - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Errno::EPROTO

Protocol error.

In Files

  • lib/webrick/compat.rb

Parent

SystemCallError


module Etc - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Etc

The Etc module provides access to information typically stored in files in the /etc directory on Unix systems.

The information accessible consists of the information found in the /etc/passwd and /etc/group files, plus information about the system's temporary directory (/tmp) and configuration directory (/etc).

The Etc module provides a more reliable way to access information about the logged in user than environment variables such as +$USER+.

Example:

require 'etc'

login = Etc.getlogin
info = Etc.getpwnam(login)
username = info.gecos.split(/,/).first
puts "Hello #{username}, I see your login name is #{login}"

Note that the methods provided by this module are not always secure. It should be used for informational purposes, and not for security.

All operations defined in this module are class methods, so that you can include the Etc module into your class.

In Files

  • ext/etc/etc.c

Constants

Group

is an Array of Strings containing the short login names of the

members of the group.
Passwd

account expiration time(integer) must be compiled with HAVE_ST_PW_EXPIRE

Public Class Methods

endgrent() click to toggle source

Ends the process of scanning through the /etc/group file begun by ::getgrent, and closes the file.

static VALUE
etc_endgrent(VALUE obj)
{
#ifdef HAVE_GETGRENT
    endgrent();
#endif
    return Qnil;
}
endpwent() click to toggle source

Ends the process of scanning through the /etc/passwd file begun with ::getpwent, and closes the file.

static VALUE
etc_endpwent(VALUE obj)
{
#ifdef HAVE_GETPWENT
    endpwent();
#endif
    return Qnil;
}
getgrent() click to toggle source

Returns an entry from the /etc/group file.

The first time it is called it opens the file and returns the first entry; each successive call returns the next entry, or nil if the end of the file has been reached.

To close the file when processing is complete, call ::endgrent.

Each entry is returned as a Group struct

static VALUE
etc_getgrent(VALUE obj)
{
#ifdef HAVE_GETGRENT
    struct group *gr;

    if (gr = getgrent()) {
        return setup_group(gr);
    }
#endif
    return Qnil;
}
getgrgid(group_id) → Group click to toggle source

Returns information about the group with specified integer group_id, as found in /etc/group.

The information is returned as a Group struct.

See the unix manpage for getgrgid(3) for more detail.

Example:

Etc.getgrgid(100)
#=> #<struct Struct::Group name="users", passwd="x", gid=100, mem=["meta", "root"]>

static VALUE
etc_getgrgid(int argc, VALUE *argv, VALUE obj)
{
#ifdef HAVE_GETGRENT
    VALUE id;
    gid_t gid;
    struct group *grp;

    rb_secure(4);
    if (rb_scan_args(argc, argv, "01", &id) == 1) {
        gid = NUM2GIDT(id);
    }
    else {
        gid = getgid();
    }
    grp = getgrgid(gid);
    if (grp == 0) rb_raise(rb_eArgError, "can't find group for %d", (int)gid);
    return setup_group(grp);
#else
    return Qnil;
#endif
}
getgrnam(name) → Group click to toggle source

Returns information about the group with specified name, as found in /etc/group.

The information is returned as a Group struct.

See the unix manpage for getgrnam(3) for more detail.

Example:

Etc.getgrnam('users')
#=> #<struct Struct::Group name="users", passwd="x", gid=100, mem=["meta", "root"]>

static VALUE
etc_getgrnam(VALUE obj, VALUE nam)
{
#ifdef HAVE_GETGRENT
    struct group *grp;

    rb_secure(4);
    SafeStringValue(nam);
    grp = getgrnam(RSTRING_PTR(nam));
    if (grp == 0) rb_raise(rb_eArgError, "can't find group for %"PRIsVALUE, nam);
    return setup_group(grp);
#else
    return Qnil;
#endif
}
getlogin → String click to toggle source

Returns the short user name of the currently logged in user. Unfortunately, it is often rather easy to fool ::getlogin.

Avoid ::getlogin for security-related purposes.

If ::getlogin fails, try ::getpwuid.

See the unix manpage for getpwuid(3) for more detail.

e.g.

Etc.getlogin -> 'guest'
static VALUE
etc_getlogin(VALUE obj)
{
    char *login;

    rb_secure(4);
#ifdef HAVE_GETLOGIN
    login = getlogin();
    if (!login) login = getenv("USER");
#else
    login = getenv("USER");
#endif

    if (login)
        return rb_tainted_str_new2(login);
    return Qnil;
}
getpwent() click to toggle source

Returns an entry from the /etc/passwd file.

The first time it is called it opens the file and returns the first entry; each successive call returns the next entry, or nil if the end of the file has been reached.

To close the file when processing is complete, call ::endpwent.

Each entry is returned as a Passwd struct.

static VALUE
etc_getpwent(VALUE obj)
{
#ifdef HAVE_GETPWENT
    struct passwd *pw;

    if (pw = getpwent()) {
        return setup_passwd(pw);
    }
#endif
    return Qnil;
}
getpwnam(name) → Passwd click to toggle source

Returns the /etc/passwd information for the user with specified login name.

The information is returned as a Passwd struct.

See the unix manpage for getpwnam(3) for more detail.

Example:

Etc.getpwnam('root')
#=> #<struct Struct::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash">

static VALUE
etc_getpwnam(VALUE obj, VALUE nam)
{
#ifdef HAVE_GETPWENT
    struct passwd *pwd;

    SafeStringValue(nam);
    pwd = getpwnam(RSTRING_PTR(nam));
    if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %"PRIsVALUE, nam);
    return setup_passwd(pwd);
#else
    return Qnil;
#endif
}
getpwuid(uid) → Passwd click to toggle source

Returns the /etc/passwd information for the user with the given integer uid.

The information is returned as a Passwd struct.

If uid is omitted, the value from Passwd[:uid] is returned instead.

See the unix manpage for getpwuid(3) for more detail.

Example:

Etc.getpwuid(0)
#=> #<struct Struct::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash">

static VALUE
etc_getpwuid(int argc, VALUE *argv, VALUE obj)
{
#if defined(HAVE_GETPWENT)
    VALUE id;
    rb_uid_t uid;
    struct passwd *pwd;

    rb_secure(4);
    if (rb_scan_args(argc, argv, "01", &id) == 1) {
        uid = NUM2UIDT(id);
    }
    else {
        uid = getuid();
    }
    pwd = getpwuid(uid);
    if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %d", (int)uid);
    return setup_passwd(pwd);
#else
    return Qnil;
#endif
}
group() click to toggle source

Provides a convenient Ruby iterator which executes a block for each entry in the /etc/group file.

The code block is passed an Group struct.

See ::getgrent above for details.

Example:

require 'etc'

Etc.group {|g|
  puts g.name + ": " + g.mem.join(', ')
}

static VALUE
etc_group(VALUE obj)
{
#ifdef HAVE_GETGRENT
    struct group *grp;

    rb_secure(4);
    if (rb_block_given_p()) {
        each_group();
    }
    else if (grp = getgrent()) {
        return setup_group(grp);
    }
#endif
    return Qnil;
}
passwd { |struct| block } → Passwd click to toggle source
passwd → Passwd

Provides a convenient Ruby iterator which executes a block for each entry in the /etc/passwd file.

The code block is passed an Passwd struct.

See ::getpwent above for details.

Example:

require 'etc'

Etc.passwd {|u|
  puts u.name + " = " + u.gecos
}

static VALUE
etc_passwd(VALUE obj)
{
#ifdef HAVE_GETPWENT
    struct passwd *pw;

    rb_secure(4);
    if (rb_block_given_p()) {
        each_passwd();
    }
    else if (pw = getpwent()) {
        return setup_passwd(pw);
    }
#endif
    return Qnil;
}
setgrent() click to toggle source

Resets the process of reading the /etc/group file, so that the next call to ::getgrent will return the first entry again.

static VALUE
etc_setgrent(VALUE obj)
{
#ifdef HAVE_GETGRENT
    setgrent();
#endif
    return Qnil;
}
setpwent() click to toggle source

Resets the process of reading the /etc/passwd file, so that the next call to ::getpwent will return the first entry again.

static VALUE
etc_setpwent(VALUE obj)
{
#ifdef HAVE_GETPWENT
    setpwent();
#endif
    return Qnil;
}
sysconfdir() click to toggle source

Returns system configuration directory.

This is typically “/etc”, but is modified by the prefix used when Ruby was compiled. For example, if Ruby is built and installed in /usr/local, returns “/usr/local/etc”.

static VALUE
etc_sysconfdir(VALUE obj)
{
#ifdef _WIN32
    return rb_w32_special_folder(CSIDL_COMMON_APPDATA);
#else
    return rb_filesystem_str_new_cstr(SYSCONFDIR);
#endif
}
systmpdir() click to toggle source

Returns system temporary directory; typically “/tmp”.

static VALUE
etc_systmpdir(void)
{
    VALUE tmpdir;
#ifdef _WIN32
    WCHAR path[_MAX_PATH];
    UINT len = rb_w32_system_tmpdir(path, numberof(path));
    if (!len) return Qnil;
    tmpdir = rb_w32_conv_from_wchar(path, rb_filesystem_encoding());
#else
    tmpdir = rb_filesystem_str_new_cstr("/tmp");
#endif
    FL_UNSET(tmpdir, FL_TAINT|FL_UNTRUSTED);
    return tmpdir;
}


class Exception - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Exception

Exception serialization/deserialization

In Files

  • ext/json/lib/json/add/exception.rb

Parent

Object

Public Class Methods

json_create(object) click to toggle source

Deserializes JSON string by constructing new Exception object with message m and backtrace b serialized with to_json

# File ext/json/lib/json/add/exception.rb, line 10
def self.json_create(object)
  result = new(object['m'])
  result.set_backtrace object['b']
  result
end

Public Instance Methods

as_json(*) click to toggle source

Returns a hash, that will be turned into a JSON object and represent this object.

# File ext/json/lib/json/add/exception.rb, line 18
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'm'            => message,
    'b'            => backtrace,
  }
end
to_json(*args) click to toggle source

Stores class name (Exception) with message m and backtrace array b as JSON string

# File ext/json/lib/json/add/exception.rb, line 28
def to_json(*args)
  as_json.to_json(*args)
end


module Exception2MessageMapper::E2MM - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Exception2MessageMapper::E2MM

e2mmap.rb - for ruby 1.1
    $Release Version: 2.0$
    $Revision: 1.10 $
    by Keiju ISHITSUKA

–

Usage:

U1)

class Foo
  extend Exception2MessageMapper
  def_e2message ExistingExceptionClass, "message..."
  def_exception :NewExceptionClass, "message..."[, superclass]
  ...
end

U2)

module Error
  extend Exception2MessageMapper
  def_e2meggage ExistingExceptionClass, "message..."
  def_exception :NewExceptionClass, "message..."[, superclass]
  ...
end
class Foo
  include Error
  ...
end

foo = Foo.new
foo.Fail ....

U3)

module Error
  extend Exception2MessageMapper
  def_e2message ExistingExceptionClass, "message..."
  def_exception :NewExceptionClass, "message..."[, superclass]
  ...
end
class Foo
  extend Exception2MessageMapper
  include Error
  ...
end

Foo.Fail NewExceptionClass, arg...
Foo.Fail ExistingExceptionClass, arg...

In Files

  • lib/e2mmap.rb

Constants

E2MM

Public Class Methods

Fail(klass = E2MM, err = nil, *rest) click to toggle source
Alias for: Raise
Raise(klass = E2MM, err = nil, *rest) click to toggle source

Fail(klass, err, *rest)

klass:  class to define exception under.
err:    exception
rest:   message arguments

# File lib/e2mmap.rb, line 138
def E2MM.Raise(klass = E2MM, err = nil, *rest)
  if form = e2mm_message(klass, err)
    b = $@.nil? ? caller(1) : $@
    #p $@
    #p __FILE__
    b.shift if b[0] =~ /^#{Regexp.quote(__FILE__)}:/
    raise err, sprintf(form, *rest), b
  else
    E2MM.Fail E2MM, ErrNotRegisteredException, err.inspect
  end
end
Also aliased as: Fail
def_e2message(k, c, m) click to toggle source

#def_e2message(k, e, m)

    k:  class to define exception under.
    e:  exception
    m:  message_form
define exception c with message m.

# File lib/e2mmap.rb, line 114
def E2MM.def_e2message(k, c, m)
  E2MM.instance_eval{@MessageMap[[k, c]] = m}
  c
end
def_exception(k, n, m, s = StandardError) click to toggle source

#def_exception(k, n, m, s)

    k:  class to define exception under.
    n:  exception_name
    m:  message_form
    s:  superclass(default: StandardError)
define exception named %x`c'' with message m.

# File lib/e2mmap.rb, line 126
def E2MM.def_exception(k, n, m, s = StandardError)
  n = n.id2name if n.kind_of?(Fixnum)
  e = Class.new(s)
  E2MM.instance_eval{@MessageMap[[k, e]] = m}
  k.const_set(n, e)
end
e2mm_message(klass, exp) click to toggle source
# File lib/e2mmap.rb, line 153
def E2MM.e2mm_message(klass, exp)
  for c in klass.ancestors
    if mes = @MessageMap[[c,exp]]
      #p mes
      m = klass.instance_eval('"' + mes + '"')
      return m
    end
  end
  nil
end
Also aliased as: message
extend_object(cl) click to toggle source
# File lib/e2mmap.rb, line 55
def E2MM.extend_object(cl)
  super
  cl.bind(self) unless cl < E2MM
end
message(klass, exp) click to toggle source
Alias for: e2mm_message

Public Instance Methods

Fail(err = nil, *rest) click to toggle source
Alias for: Raise
Raise(err = nil, *rest) click to toggle source

Fail(err, *rest)

err:    exception
rest:   message arguments
# File lib/e2mmap.rb, line 77
def Raise(err = nil, *rest)
  E2MM.Raise(self, err, *rest)
end
Also aliased as: Fail, fail
bind(cl) click to toggle source
# File lib/e2mmap.rb, line 60
def bind(cl)
  self.module_eval %Q[
    def Raise(err = nil, *rest)
      Exception2MessageMapper.Raise(self.class, err, *rest)
    end
    alias Fail Raise

    def self.included(mod)
      mod.extend Exception2MessageMapper
    end
  ]
end
def_e2message(c, m) click to toggle source

#def_e2message(c, m)

    c:  exception
    m:  message_form
define exception c with message m.
# File lib/e2mmap.rb, line 88
def def_e2message(c, m)
  E2MM.def_e2message(self, c, m)
end
def_exception(n, m, s = StandardError) click to toggle source

#def_exception(n, m, s)

    n:  exception_name
    m:  message_form
    s:  superclass(default: StandardError)
define exception named ``c'' with message m.
# File lib/e2mmap.rb, line 98
def def_exception(n, m, s = StandardError)
  E2MM.def_exception(self, n, m, s)
end
fail(err = nil, *rest) click to toggle source
Alias for: Raise


module Fcntl - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Fcntl

Fcntl loads the constants defined in the system's <fcntl.h> C header file, and used with both the fcntl(2) and open(2) POSIX system calls.

To perform a fcntl(2) operation, use IO::fcntl.

To perform an open(2) operation, use IO::sysopen.

The set of operations and constants available depends upon specific operating system. Some values listed below may not be supported on your system.

See your fcntl(2) man page for complete details.

Open /tmp/tempfile as a write-only file that is created if it doesn't exist:

require 'fcntl'

fd = IO.sysopen('/tmp/tempfile',
                Fcntl::O_WRONLY | Fcntl::O_EXCL | Fcntl::O_CREAT)
f = IO.open(fd)
f.syswrite("TEMP DATA")
f.close

Get the flags on file s:

m = s.fcntl(Fcntl::F_GETFL, 0)

Set the non-blocking flag on f in addition to the existing flags in m.

f.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK|m)

In Files

  • ext/fcntl/fcntl.c

Constants

FD_CLOEXEC

FD_CLOEXEC

the value of the close-on-exec flag.

F_DUPFD

F_DUPFD

Duplicate a file descriptor to the mimimum unused file descriptor greater than or equal to the argument.

The close-on-exec flag of the duplicated file descriptor is set. (Ruby uses F_DUPFD_CLOEXEC internally if available to avoid race condition. F_SETFD is used if F_DUPFD_CLOEXEC is not available.)

F_GETFD

F_GETFD

Read the close-on-exec flag of a file descriptor.

F_GETFL

F_GETFL

Get the file descriptor flags. This will be one or more of the O_* flags.

F_GETLK

F_GETLK

Determine whether a given region of a file is locked. This uses one of the F_*LK flags.

F_RDLCK

F_RDLCK

Read lock for a region of a file

F_SETFD

F_SETFD

Set the close-on-exec flag of a file descriptor.

F_SETFL

F_SETFL

Set the file descriptor flags. This will be one or more of the O_* flags.

F_SETLK

F_SETLK

Acquire a lock on a region of a file. This uses one of the F_*LCK flags.

F_SETLKW

F_SETLKW

Acquire a lock on a region of a file, waiting if necessary. This uses one of the F_*LCK flags

F_UNLCK

F_UNLCK

Remove lock for a region of a file

F_WRLCK

F_WRLCK

Write lock for a region of a file

O_ACCMODE

O_ACCMODE

Mask to extract the read/write flags

O_APPEND

O_APPEND

Open the file in append mode

O_CREAT

O_CREAT

Create the file if it doesn't exist

O_EXCL

O_EXCL

Used with O_CREAT, fail if the file exists

O_NDELAY

O_NDELAY

Open the file in non-blocking mode

O_NOCTTY

O_NOCTTY

Open TTY without it becoming the controlling TTY

O_NONBLOCK

O_NONBLOCK

Open the file in non-blocking mode

O_RDONLY

O_RDONLY

Open the file in read-only mode

O_RDWR

O_RDWR

Open the file in read-write mode

O_TRUNC

O_TRUNC

Truncate the file on open

O_WRONLY

O_WRONLY

Open the file in write-only mode.


module Fiddle - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Fiddle

A libffi wrapper for Ruby.

Description

Fiddle is an extension to translate a foreign function interface (FFI) with ruby.

It wraps libffi, a popular C library which provides a portable interface that allows code written in one language to clal code written in another language.

Example

Here we will use Fiddle::Function to wrap floor(3) from libm

require 'fiddle'

libm = Fiddle.dlopen('/lib/libm.so.6')

floor = Fiddle::Function.new(
  libm['floor'],
  [Fiddle::TYPE_DOUBLE],
  Fiddle::TYPE_DOUBLE
)

puts floor.call(3.14159) #=> 3.0

In Files

  • ext/fiddle/closure.c
  • ext/fiddle/fiddle.c
  • ext/fiddle/lib/fiddle/closure.rb
  • ext/fiddle/lib/fiddle/cparser.rb
  • ext/fiddle/lib/fiddle/function.rb
  • ext/fiddle/lib/fiddle/import.rb
  • ext/fiddle/lib/fiddle/pack.rb
  • ext/fiddle/lib/fiddle/struct.rb
  • ext/fiddle/lib/fiddle/types.rb
  • ext/fiddle/lib/fiddle/value.rb
  • ext/fiddle/lib/fiddle.rb

Constants

ALIGN_CHAR

ALIGN_CHAR

The alignment size of a char

ALIGN_DOUBLE

ALIGN_DOUBLE

The alignment size of a double

ALIGN_FLOAT

ALIGN_FLOAT

The alignment size of a float

ALIGN_INT

ALIGN_INT

The alignment size of an int

ALIGN_INTPTR_T

ALIGN_INTPTR_T

The alignment size of a intptr_t

ALIGN_LONG

ALIGN_LONG

The alignment size of a long

ALIGN_LONG_LONG

ALIGN_LONG_LONG

The alignment size of a long long

ALIGN_PTRDIFF_T

ALIGN_PTRDIFF_T

The alignment size of a ptrdiff_t

ALIGN_SHORT

ALIGN_SHORT

The alignment size of a short

ALIGN_SIZE_T

ALIGN_SIZE_T

The alignment size of a size_t

ALIGN_SSIZE_T

ALIGN_SSIZE_T

The alignment size of a ssize_t

ALIGN_UINTPTR_T

ALIGN_UINTPTR_T

The alignment size of a uintptr_t

ALIGN_VOIDP

ALIGN_VOIDP

The alignment size of a void*

BUILD_RUBY_PLATFORM

BUILD_RUBY_PLATFORM

Platform built against (i.e. “x86_64-linux”, etc.)

See also RUBY_PLATFORM

RUBY_FREE

RUBY_FREE

Address of the ruby_xfree() function

SIZEOF_CHAR

SIZEOF_CHAR

size of a char

SIZEOF_DOUBLE

SIZEOF_DOUBLE

size of a double

SIZEOF_FLOAT

SIZEOF_FLOAT

size of a float

SIZEOF_INT

SIZEOF_INT

size of an int

SIZEOF_INTPTR_T

SIZEOF_INTPTR_T

size of a intptr_t

SIZEOF_LONG

SIZEOF_LONG

size of a long

SIZEOF_LONG_LONG

SIZEOF_LONG_LONG

size of a long long

SIZEOF_PTRDIFF_T

SIZEOF_PTRDIFF_T

size of a ptrdiff_t

SIZEOF_SHORT

SIZEOF_SHORT

size of a short

SIZEOF_SIZE_T

SIZEOF_SIZE_T

size of a size_t

SIZEOF_SSIZE_T

SIZEOF_SSIZE_T

size of a ssize_t

SIZEOF_UINTPTR_T

SIZEOF_UINTPTR_T

size of a uintptr_t

SIZEOF_VOIDP

SIZEOF_VOIDP

size of a void*

TYPE_CHAR

TYPE_CHAR

C type - char

TYPE_DOUBLE

TYPE_DOUBLE

C type - double

TYPE_FLOAT

TYPE_FLOAT

C type - float

TYPE_INT

TYPE_INT

C type - int

TYPE_INTPTR_T

TYPE_INTPTR_T

C type - intptr_t

TYPE_LONG

TYPE_LONG

C type - long

TYPE_LONG_LONG

TYPE_LONG_LONG

C type - long long

TYPE_PTRDIFF_T

TYPE_PTRDIFF_T

C type - ptrdiff_t

TYPE_SHORT

TYPE_SHORT

C type - short

TYPE_SIZE_T

TYPE_SIZE_T

C type - size_t

TYPE_SSIZE_T

TYPE_SSIZE_T

C type - ssize_t

TYPE_UINTPTR_T

TYPE_UINTPTR_T

C type - uintptr_t

TYPE_VOID

TYPE_VOID

C type - void

TYPE_VOIDP

TYPE_VOIDP

C type - void*

WINDOWS

Returns a boolean regarding whether the host is WIN32

Public Class Methods

dlopen(library) → Fiddle::Handle click to toggle source

Creates a new handler that opens library, and returns an instance of Fiddle::Handle.

See Fiddle::Handle.new for more.

# File ext/fiddle/lib/fiddle.rb, line 36
def dlopen library
  Fiddle::Handle.new library
end
dlunwrap(addr) click to toggle source

Returns the hexadecimal representation of a memory pointer address addr

Example:

lib = Fiddle.dlopen('/lib64/libc-2.15.so')
=> #<Fiddle::Handle:0x00000001342460>

lib['strcpy'].to_s(16)
=> "7f59de6dd240"

Fiddle.dlunwrap(Fiddle.dlwrap(lib['strcpy'].to_s(16)))
=> "7f59de6dd240"

VALUE
rb_fiddle_ptr2value(VALUE self, VALUE addr)
{
    rb_secure(4);
    return (VALUE)NUM2PTR(addr);
}
dlwrap(val) click to toggle source

Returns a memory pointer of a function's hexadecimal address location val

Example:

lib = Fiddle.dlopen('/lib64/libc-2.15.so')
=> #<Fiddle::Handle:0x00000001342460>

Fiddle.dlwrap(lib['strcpy'].to_s(16))
=> 25522520

static VALUE
rb_fiddle_value2ptr(VALUE self, VALUE val)
{
    return PTR2NUM((void*)val);
}
free(addr) click to toggle source

Free the memory at address addr

VALUE
rb_fiddle_free(VALUE self, VALUE addr)
{
    void *ptr = NUM2PTR(addr);

    rb_secure(4);
    ruby_xfree(ptr);
    return Qnil;
}
last_error() click to toggle source

Returns the last Error of the current executing Thread or nil if none

# File ext/fiddle/lib/fiddle.rb, line 20
def self.last_error
  Thread.current[:__FIDDLE_LAST_ERROR__]
end
last_error=(error) click to toggle source

Sets the last Error of the current executing Thread to error

# File ext/fiddle/lib/fiddle.rb, line 25
def self.last_error= error
  Thread.current[:__DL2_LAST_ERROR__] = error
  Thread.current[:__FIDDLE_LAST_ERROR__] = error
end
malloc(size) click to toggle source

Allocate size bytes of memory and return the integer memory address for the allocated memory.

static VALUE
rb_fiddle_malloc(VALUE self, VALUE size)
{
    void *ptr;

    rb_secure(4);
    ptr = (void*)ruby_xmalloc(NUM2INT(size));
    return PTR2NUM(ptr);
}
realloc(addr, size) click to toggle source

Change the size of the memory allocated at the memory location addr to size bytes. Returns the memory address of the reallocated memory, which may be different than the address passed in.

static VALUE
rb_fiddle_realloc(VALUE self, VALUE addr, VALUE size)
{
    void *ptr = NUM2PTR(addr);

    rb_secure(4);
    ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size));
    return PTR2NUM(ptr);
}
win32_last_error() click to toggle source

Returns the last win32 Error of the current executing Thread or nil if none

# File ext/fiddle/lib/fiddle.rb, line 9
def self.win32_last_error
  Thread.current[:__FIDDLE_WIN32_LAST_ERROR__]
end
win32_last_error=(error) click to toggle source

Sets the last win32 Error of the current executing Thread to error

# File ext/fiddle/lib/fiddle.rb, line 14
def self.win32_last_error= error
  Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error
end


module Fiddle::BasicTypes - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Fiddle::BasicTypes

Adds basic type aliases to the including class for use with Fiddle::Importer.

The aliases added are uint and u_int (unsigned int) and ulong and u_long (unsigned long)

In Files

  • ext/fiddle/lib/fiddle/types.rb


module Fiddle::CParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Fiddle::CParser

A mixin that provides methods for parsing C struct and prototype signatures.

Example

require 'fiddle/import'

include Fiddle::CParser
  #=> Object

parse_ctype('int increment(int)')
  #=> ["increment", Fiddle::TYPE_INT, [Fiddle::TYPE_INT]]

In Files

  • ext/fiddle/lib/fiddle/cparser.rb

Public Instance Methods

parse_ctype(ty, tymap=nil) click to toggle source

Given a String of C type ty, returns the corresponding Fiddle constant.

ty can also accept an Array of C type Strings, and will be returned in a corresponding Array.

If Hash tymap is provided, ty is expected to be the key, and the value will be the C type to be looked up.

Example:

include Fiddle::CParser
  #=> Object

parse_ctype('int')
  #=> Fiddle::TYPE_INT

parse_ctype('double')
  #=> Fiddle::TYPE_DOUBLE

parse_ctype('unsigned char')
  #=> -Fiddle::TYPE_CHAR

# File ext/fiddle/lib/fiddle/cparser.rb, line 116
def parse_ctype(ty, tymap=nil)
  tymap ||= {}
  case ty
  when Array
    return [parse_ctype(ty[0], tymap), ty[1]]
  when "void"
    return TYPE_VOID
  when "char"
    return TYPE_CHAR
  when "unsigned char"
    return  -TYPE_CHAR
  when "short"
    return TYPE_SHORT
  when "unsigned short"
    return -TYPE_SHORT
  when "int"
    return TYPE_INT
  when "unsigned int", 'uint'
    return -TYPE_INT
  when "long"
    return TYPE_LONG
  when "unsigned long"
    return -TYPE_LONG
  when "long long"
    if( defined?(TYPE_LONG_LONG) )
      return TYPE_LONG_LONG
    else
      raise(RuntimeError, "unsupported type: #{ty}")
    end
  when "unsigned long long"
    if( defined?(TYPE_LONG_LONG) )
      return -TYPE_LONG_LONG
    else
      raise(RuntimeError, "unsupported type: #{ty}")
    end
  when "float"
    return TYPE_FLOAT
  when "double"
    return TYPE_DOUBLE
  when "size_t"
    return TYPE_SIZE_T
  when "ssize_t"
    return TYPE_SSIZE_T
  when "ptrdiff_t"
    return TYPE_PTRDIFF_T
  when "intptr_t"
    return TYPE_INTPTR_T
  when "uintptr_t"
    return TYPE_UINTPTR_T
  when /\*/, /\[\s*\]/
    return TYPE_VOIDP
  else
    if( tymap[ty] )
      return parse_ctype(tymap[ty], tymap)
    else
      raise(DLError, "unknown type: #{ty}")
    end
  end
end
parse_signature(signature, tymap=nil) click to toggle source

Parses a C prototype signature

If Hash tymap is provided, the return value and the arguments from the signature are expected to be keys, and the value will be the C type to be looked up.

Example:

include Fiddle::CParser
  #=> Object

parse_signature('double sum(double, double)')
  #=> ["sum", Fiddle::TYPE_DOUBLE, [Fiddle::TYPE_DOUBLE, Fiddle::TYPE_DOUBLE]]

# File ext/fiddle/lib/fiddle/cparser.rb, line 73
def parse_signature(signature, tymap=nil)
  tymap ||= {}
  signature = signature.gsub(/\s+/, " ").strip
  case signature
  when /^([\w@\*\s]+)\(([\w\*\s\,\[\]]*)\)$/
    ret = $1
    (args = $2).strip!
    ret = ret.split(/\s+/)
    args = args.split(/\s*,\s*/)
    func = ret.pop
    if( func =~ /^\*/ )
      func.gsub!(/^\*+/,"")
      ret.push("*")
    end
    ret  = ret.join(" ")
    return [func, parse_ctype(ret, tymap), args.collect{|arg| parse_ctype(arg, tymap)}]
  else
    raise(RuntimeError,"can't parse the function prototype: #{signature}")
  end
end
parse_struct_signature(signature, tymap=nil) click to toggle source

Parses a C struct's members

Example:

include Fiddle::CParser
  #=> Object

parse_struct_signature(['int i', 'char c'])
  #=> [[Fiddle::TYPE_INT, Fiddle::TYPE_CHAR], ["i", "c"]]

# File ext/fiddle/lib/fiddle/cparser.rb, line 24
def parse_struct_signature(signature, tymap=nil)
  if( signature.is_a?(String) )
    signature = signature.split(/\s*,\s*/)
  end
  mems = []
  tys  = []
  signature.each{|msig|
    tks = msig.split(/\s+(\*)?/)
    ty = tks[0..-2].join(" ")
    member = tks[-1]

    case ty
    when /\[(\d+)\]/
      n = $1.to_i
      ty.gsub!(/\s*\[\d+\]/,"")
      ty = [ty, n]
    when /\[\]/
      ty.gsub!(/\s*\[\]/, "*")
    end

    case member
    when /\[(\d+)\]/
      ty = [ty, $1.to_i]
      member.gsub!(/\s*\[\d+\]/,"")
    when /\[\]/
      ty = ty + "*"
      member.gsub!(/\s*\[\]/, "")
    end

    mems.push(member)
    tys.push(parse_ctype(ty,tymap))
  }
  return tys, mems
end


class Fiddle::CStruct - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fiddle::CStruct

C struct shell

In Files

  • ext/fiddle/lib/fiddle/struct.rb

Parent

Object

Public Class Methods

entity_class() click to toggle source

accessor to Fiddle::CStructEntity

# File ext/fiddle/lib/fiddle/struct.rb, line 9
def CStruct.entity_class
  CStructEntity
end


module Fiddle::CStructBuilder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Fiddle::CStructBuilder

Used to construct C classes (CUnion, CStruct, etc)

Fiddle::Importer#struct and Fiddle::Importer#union wrap this functionality in an easy-to-use manner.

In Files

  • ext/fiddle/lib/fiddle/struct.rb

Public Class Methods

create(klass, types, members) click to toggle source

Construct a new class given a C:

  • class klass (CUnion, CStruct, or other that provide an entity_class)

  • types (Fiddle::TYPE_INT, Fiddle::TYPE_SIZE_T, etc., see the C types constants)

  • corresponding members

Fiddle::Importer#struct and Fiddle::Importer#union wrap this functionality in an easy-to-use manner.

Example:

require 'fiddle/struct'
require 'fiddle/cparser'

include Fiddle::CParser

types, members = parse_struct_signature(['int i','char c'])

MyStruct = Fiddle::CStructBuilder.create(Fiddle::CUnion, types, members)

obj = MyStruct.allocate

# File ext/fiddle/lib/fiddle/struct.rb, line 50
    def create(klass, types, members)
      new_class = Class.new(klass){
        define_method(:initialize){|addr|
          @entity = klass.entity_class.new(addr, types)
          @entity.assign_names(members)
        }
        define_method(:to_ptr){ @entity }
        define_method(:to_i){ @entity.to_i }
        members.each{|name|
          define_method(name){ @entity[name] }
          define_method(name + "="){|val| @entity[name] = val }
        }
      }
      size = klass.entity_class.size(types)
      new_class.module_eval("        def new_class.size()
          #{size}
        end
        def new_class.malloc()
          addr = Fiddle.malloc(#{size})
          new(addr)
        end
", __FILE__, __LINE__+1)
      return new_class
    end


class Fiddle::CStructEntity - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fiddle::CStructEntity

A C struct wrapper

In Files

  • ext/fiddle/lib/fiddle/struct.rb

Parent

Fiddle::Pointer

Public Class Methods

malloc(types, func = nil) click to toggle source

Allocates a C struct with the types provided.

When the instance is garbage collected, the C function func is called.

# File ext/fiddle/lib/fiddle/struct.rb, line 86
def CStructEntity.malloc(types, func = nil)
  addr = Fiddle.malloc(CStructEntity.size(types))
  CStructEntity.new(addr, types, func)
end
new(addr, types, func = nil) click to toggle source

Wraps the C pointer addr as a C struct with the given types.

When the instance is garbage collected, the C function func is called.

See also Fiddle::Pointer.new

# File ext/fiddle/lib/fiddle/struct.rb, line 119
def initialize(addr, types, func = nil)
  set_ctypes(types)
  super(addr, @size, func)
end
size(types) click to toggle source

Returns the offset for the packed sizes for the given types.

Fiddle::CStructEntity.size(
  [ Fiddle::TYPE_DOUBLE,
    Fiddle::TYPE_INT,
    Fiddle::TYPE_CHAR,
    Fiddle::TYPE_VOIDP ]) #=> 24

# File ext/fiddle/lib/fiddle/struct.rb, line 98
def CStructEntity.size(types)
  offset = 0

  max_align = types.map { |type, count = 1|
    last_offset = offset

    align = PackInfo::ALIGN_MAP[type]
    offset = PackInfo.align(last_offset, align) +
             (PackInfo::SIZE_MAP[type] * count)

    align
  }.max

  PackInfo.align(offset, max_align)
end

Public Instance Methods

[](name) click to toggle source

Fetch struct member name

# File ext/fiddle/lib/fiddle/struct.rb, line 151
def [](name)
  idx = @members.index(name)
  if( idx.nil? )
    raise(ArgumentError, "no such member: #{name}")
  end
  ty = @ctypes[idx]
  if( ty.is_a?(Array) )
    r = super(@offset[idx], SIZE_MAP[ty[0]] * ty[1])
  else
    r = super(@offset[idx], SIZE_MAP[ty.abs])
  end
  packer = Packer.new([ty])
  val = packer.unpack([r])
  case ty
  when Array
    case ty[0]
    when TYPE_VOIDP
      val = val.collect{|v| Pointer.new(v)}
    end
  when TYPE_VOIDP
    val = Pointer.new(val[0])
  else
    val = val[0]
  end
  if( ty.is_a?(Integer) && (ty < 0) )
    return unsigned_value(val, ty)
  elsif( ty.is_a?(Array) && (ty[0] < 0) )
    return val.collect{|v| unsigned_value(v,ty[0])}
  else
    return val
  end
end
[]=(name, val) click to toggle source

Set struct member name, to value val

# File ext/fiddle/lib/fiddle/struct.rb, line 185
def []=(name, val)
  idx = @members.index(name)
  if( idx.nil? )
    raise(ArgumentError, "no such member: #{name}")
  end
  ty  = @ctypes[idx]
  packer = Packer.new([ty])
  val = wrap_arg(val, ty, [])
  buff = packer.pack([val].flatten())
  super(@offset[idx], buff.size, buff)
  if( ty.is_a?(Integer) && (ty < 0) )
    return unsigned_value(val, ty)
  elsif( ty.is_a?(Array) && (ty[0] < 0) )
    return val.collect{|v| unsigned_value(v,ty[0])}
  else
    return val
  end
end
assign_names(members) click to toggle source

Set the names of the members in this C struct

# File ext/fiddle/lib/fiddle/struct.rb, line 125
def assign_names(members)
  @members = members
end
set_ctypes(types) click to toggle source

Calculates the offsets and sizes for the given types in the struct.

# File ext/fiddle/lib/fiddle/struct.rb, line 130
def set_ctypes(types)
  @ctypes = types
  @offset = []
  offset = 0

  max_align = types.map { |type, count = 1|
    orig_offset = offset
    align = ALIGN_MAP[type]
    offset = PackInfo.align(orig_offset, align)

    @offset << offset

    offset += (SIZE_MAP[type] * count)

    align
  }.max

  @size = PackInfo.align(offset, max_align)
end


class Fiddle::CUnion - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fiddle::CUnion

C union shell

In Files

  • ext/fiddle/lib/fiddle/struct.rb

Parent

Object

Public Class Methods

entity_class() click to toggle source

accessor to Fiddle::CUnionEntity

# File ext/fiddle/lib/fiddle/struct.rb, line 17
def CUnion.entity_class
  CUnionEntity
end


class Fiddle::CUnionEntity - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fiddle::CUnionEntity

A C union wrapper

In Files

  • ext/fiddle/lib/fiddle/struct.rb

Parent

Fiddle::CStructEntity

Public Class Methods

malloc(types, func=nil) click to toggle source

Allocates a C union the types provided.

When the instance is garbage collected, the C function func is called.

# File ext/fiddle/lib/fiddle/struct.rb, line 216
def CUnionEntity.malloc(types, func=nil)
  addr = Fiddle.malloc(CUnionEntity.size(types))
  CUnionEntity.new(addr, types, func)
end
size(types) click to toggle source

Returns the size needed for the union with the given types.

Fiddle::CUnionEntity.size(
  [ Fiddle::TYPE_DOUBLE,
    Fiddle::TYPE_INT,
    Fiddle::TYPE_CHAR,
    Fiddle::TYPE_VOIDP ]) #=> 8

# File ext/fiddle/lib/fiddle/struct.rb, line 228
def CUnionEntity.size(types)
  types.map { |type, count = 1|
    PackInfo::SIZE_MAP[type] * count
  }.max
end

Public Instance Methods

set_ctypes(types) click to toggle source

Calculate the necessary offset and for each union member with the given types

# File ext/fiddle/lib/fiddle/struct.rb, line 236
def set_ctypes(types)
  @ctypes = types
  @offset = Array.new(types.length, 0)
  @size   = self.class.size types
end


class Fiddle::Closure - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fiddle::Closure

Description

An FFI closure wrapper, for handling callbacks.

Example

closure = Class.new(Fiddle::Closure) {
  def call
    10
  end
}.new(Fiddle::TYPE_INT, [])
   #=> #<#<Class:0x0000000150d308>:0x0000000150d240>
func = Fiddle::Function.new(closure, [], Fiddle::TYPE_INT)
   #=> #<Fiddle::Function:0x00000001516e58>
func.call
   #=> 10

In Files

  • ext/fiddle/closure.c
  • ext/fiddle/lib/fiddle/closure.rb

Parent

Object

Attributes

args[R]

arguments of the FFI closure

ctype[R]

the C type of the return of the FFI closure

Public Class Methods

new(ret, args, abi = Fiddle::DEFAULT) click to toggle source

Construct a new Closure object.

  • ret is the C type to be returned

  • args is an Array of arguments, passed to the callback function

  • abi is the abi of the closure

If there is an error in preparing the ffi_cif or ffi_prep_closure, then a RuntimeError will be raised.

static VALUE
initialize(int rbargc, VALUE argv[], VALUE self)
{
    VALUE ret;
    VALUE args;
    VALUE abi;
    fiddle_closure * cl;
    ffi_cif * cif;
    ffi_closure *pcl;
    ffi_status result;
    int i, argc;

    if (2 == rb_scan_args(rbargc, argv, "21", &ret, &args, &abi))
        abi = INT2NUM(FFI_DEFAULT_ABI);

    Check_Type(args, T_ARRAY);

    argc = RARRAY_LENINT(args);

    TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl);

    cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *));

    for (i = 0; i < argc; i++) {
        int type = NUM2INT(RARRAY_PTR(args)[i]);
        cl->argv[i] = INT2FFI_TYPE(type);
    }
    cl->argv[argc] = NULL;

    rb_iv_set(self, "@ctype", ret);
    rb_iv_set(self, "@args", args);

    cif = &cl->cif;
    pcl = cl->pcl;

    result = ffi_prep_cif(cif, NUM2INT(abi), argc,
                INT2FFI_TYPE(NUM2INT(ret)),
                cl->argv);

    if (FFI_OK != result)
        rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);

#ifndef DONT_USE_FFI_CLOSURE_ALLOC
    result = ffi_prep_closure_loc(pcl, cif, callback,
                (void *)self, cl->code);
#else
    result = ffi_prep_closure(pcl, cif, callback, (void *)self);
    cl->code = (void *)pcl;
    i = mprotect(pcl, sizeof(*pcl), PROT_READ | PROT_EXEC);
    if (i) {
        rb_sys_fail("mprotect");
    }
#endif

    if (FFI_OK != result)
        rb_raise(rb_eRuntimeError, "error prepping closure %d", result);

    return self;
}

Public Instance Methods

to_i() click to toggle source

Returns the memory address for this closure

static VALUE
to_i(VALUE self)
{
    fiddle_closure * cl;
    void *code;

    TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl);

    code = cl->code;

    return PTR2NUM(code);
}


class Fiddle::Closure::BlockCaller - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fiddle::Closure::BlockCaller

Extends Fiddle::Closure to allow for building the closure in a block

In Files

  • ext/fiddle/lib/fiddle/closure.rb

Parent

Fiddle::Closure

Public Class Methods

new(ctype, args, abi = Fiddle::Function::DEFAULT, &block) click to toggle source

Description

Construct a new BlockCaller object.

  • ctype is the C type to be returned

  • args are passed the callback

  • abi is the abi of the closure

If there is an error in preparing the ffi_cif or ffi_prep_closure, then a RuntimeError will be raised.

Example

include Fiddle

cb = Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |one|
  one
end

func = Function.new(cb, [TYPE_INT], TYPE_INT)

# File ext/fiddle/lib/fiddle/closure.rb, line 34
def initialize ctype, args, abi = Fiddle::Function::DEFAULT, &block
  super(ctype, args, abi)
  @block = block
end

Public Instance Methods

call(*args) click to toggle source

Calls the constructed BlockCaller, with args

For an example see ::new

# File ext/fiddle/lib/fiddle/closure.rb, line 43
def call *args
  @block.call(*args)
end


class Fiddle::CompositeHandler - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fiddle::CompositeHandler

Used internally by Fiddle::Importer

In Files

  • ext/fiddle/lib/fiddle/import.rb

Parent

Object

Public Class Methods

new(handlers) click to toggle source

Create a new handler with the open handlers

Used internally by Fiddle::Importer#dlload

# File ext/fiddle/lib/fiddle/import.rb, line 12
def initialize(handlers)
  @handlers = handlers
end

Public Instance Methods

[](symbol) click to toggle source

See #sym

# File ext/fiddle/lib/fiddle/import.rb, line 39
def [](symbol)
  sym(symbol)
end
handlers() click to toggle source

Array of the currently loaded libraries.

# File ext/fiddle/lib/fiddle/import.rb, line 17
def handlers()
  @handlers
end
sym(symbol) click to toggle source

Returns the address as an Integer from any handlers with the function named symbol.

Raises a DLError if the handle is closed.

# File ext/fiddle/lib/fiddle/import.rb, line 25
def sym(symbol)
  @handlers.each{|handle|
    if( handle )
      begin
        addr = handle.sym(symbol)
        return addr
      rescue DLError
      end
    end
  }
  return nil
end


class Fiddle::DLError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fiddle::DLError

standard dynamic load exception

In Files

  • ext/fiddle/closure.c

Parent

StandardError


class Fiddle::Function - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fiddle::Function

Description

A representation of a C function

Examples

'strcpy'

@libc = Fiddle.dlopen "/lib/libc.so.6"
   #=> #<Fiddle::Handle:0x00000001d7a8d8>
f = Fiddle::Function.new(
  @libc['strcpy'],
  [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP],
  Fiddle::TYPE_VOIDP)
   #=> #<Fiddle::Function:0x00000001d8ee00>
buff = "000"
   #=> "000"
str = f.call(buff, "123")
   #=> #<Fiddle::Pointer:0x00000001d0c380 ptr=0x000000018a21b8 size=0 free=0x00000000000000>
str.to_s
=> "123"

ABI check

@libc = DL.dlopen "/lib/libc.so.6"
   #=> #<Fiddle::Handle:0x00000001d7a8d8>
f = Fiddle::Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
   #=> #<Fiddle::Function:0x00000001d8ee00>
f.abi == Fiddle::Function::DEFAULT
   #=> true

In Files

  • ext/fiddle/closure.c
  • ext/fiddle/lib/fiddle/function.rb

Parent

Object

Constants

DEFAULT

DEFAULT

Default ABI

STDCALL

STDCALL

FFI implementation of WIN32 stdcall convention

Attributes

abi[R]

The ABI of the Function.

name[R]

The name of this function

ptr[R]

The address of this function

Public Class Methods

new(ptr, args, ret_type, abi = DEFAULT) click to toggle source

Constructs a Function object.

  • ptr is a referenced function, of a Fiddle::Handle

  • args is an Array of arguments, passed to the ptr function

  • ret_type is the return type of the function

  • abi is the ABI of the function

static VALUE
initialize(int argc, VALUE argv[], VALUE self)
{
    ffi_cif * cif;
    ffi_type **arg_types;
    ffi_status result;
    VALUE ptr, args, ret_type, abi, kwds;
    int i;

    rb_scan_args(argc, argv, "31:", &ptr, &args, &ret_type, &abi, &kwds);
    if(NIL_P(abi)) abi = INT2NUM(FFI_DEFAULT_ABI);

    Check_Type(args, T_ARRAY);

    rb_iv_set(self, "@ptr", ptr);
    rb_iv_set(self, "@args", args);
    rb_iv_set(self, "@return_type", ret_type);
    rb_iv_set(self, "@abi", abi);

    if (!NIL_P(kwds)) rb_hash_foreach(kwds, parse_keyword_arg_i, self);

    TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif);

    arg_types = xcalloc(RARRAY_LEN(args) + 1, sizeof(ffi_type *));

    for (i = 0; i < RARRAY_LEN(args); i++) {
        int type = NUM2INT(RARRAY_PTR(args)[i]);
        arg_types[i] = INT2FFI_TYPE(type);
    }
    arg_types[RARRAY_LEN(args)] = NULL;

    result = ffi_prep_cif (
            cif,
            NUM2INT(abi),
            RARRAY_LENINT(args),
            INT2FFI_TYPE(NUM2INT(ret_type)),
            arg_types);

    if (result)
        rb_raise(rb_eRuntimeError, "error creating CIF %d", result);

    return self;
}

Public Instance Methods

call(*args) click to toggle source

Calls the constructed Function, with args

For an example see Fiddle::Function

static VALUE
function_call(int argc, VALUE argv[], VALUE self)
{
    ffi_cif * cif;
    fiddle_generic retval;
    fiddle_generic *generic_args;
    void **values;
    VALUE cfunc, types, cPointer;
    int i;

    cfunc    = rb_iv_get(self, "@ptr");
    types    = rb_iv_get(self, "@args");
    cPointer = rb_const_get(mFiddle, rb_intern("Pointer"));

    if(argc != RARRAY_LENINT(types)) {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
                argc, RARRAY_LENINT(types));
    }

    TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif);

    if (rb_safe_level() >= 1) {
        for (i = 0; i < argc; i++) {
            VALUE src = argv[i];
            if (OBJ_TAINTED(src)) {
                rb_raise(rb_eSecurityError, "tainted parameter not allowed");
            }
        }
    }

    values = xcalloc((size_t)argc + 1, (size_t)sizeof(void *));
    generic_args = xcalloc((size_t)argc, (size_t)sizeof(fiddle_generic));

    for (i = 0; i < argc; i++) {
        VALUE type = RARRAY_PTR(types)[i];
        VALUE src = argv[i];

        if(NUM2INT(type) == TYPE_VOIDP) {
            if(NIL_P(src)) {
                src = INT2NUM(0);
            } else if(cPointer != CLASS_OF(src)) {
                src = rb_funcall(cPointer, rb_intern("[]"), 1, src);
            }
            src = rb_Integer(src);
        }

        VALUE2GENERIC(NUM2INT(type), src, &generic_args[i]);
        values[i] = (void *)&generic_args[i];
    }
    values[argc] = NULL;

    ffi_call(cif, NUM2PTR(rb_Integer(cfunc)), &retval, values);

    rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno));
#if defined(_WIN32)
    rb_funcall(mFiddle, rb_intern("win32_last_error="), 1, INT2NUM(errno));
#endif

    xfree(values);
    xfree(generic_args);

    return GENERIC2VALUE(rb_iv_get(self, "@return_type"), retval);
}
to_i() click to toggle source

The integer memory location of this function

# File ext/fiddle/lib/fiddle/function.rb, line 13
def to_i
  ptr.to_i
end


class Fiddle::Handle - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fiddle::Handle

The Fiddle::Handle is the manner to access the dynamic library

Example

Setup

libc_so = "/lib64/libc.so.6"
=> "/lib64/libc.so.6"
@handle = Fiddle::Handle.new(libc_so)
=> #<Fiddle::Handle:0x00000000d69ef8>

Setup, with flags

libc_so = "/lib64/libc.so.6"
=> "/lib64/libc.so.6"
@handle = Fiddle::Handle.new(libc_so, Fiddle::RTLD_LAZY | Fiddle::RTLD_GLOBAL)
=> #<Fiddle::Handle:0x00000000d69ef8>

See RTLD_LAZY and RTLD_GLOBAL

Addresses to symbols

strcpy_addr = @handle['strcpy']
=> 140062278451968

or

strcpy_addr = @handle.sym('strcpy')
=> 140062278451968

In Files

  • ext/fiddle/closure.c

Parent

Object

Constants

DEFAULT

DEFAULT

A predefined pseudo-handle of RTLD_DEFAULT

Which will find the first occurrence of the desired symbol using the default library search order

NEXT

NEXT

A predefined pseudo-handle of RTLD_NEXT

Which will find the next occurrence of a function in the search order after the current library.

RTLD_GLOBAL

Handle flag.

The symbols defined by this library will be made available for symbol resolution of subsequently loaded libraries.

RTLD_LAZY

Handle flag.

Perform lazy binding. Only resolve symbols as the code that references them is executed. If the symbol is never referenced, then it is never resolved. (Lazy binding is only performed for function references; references to variables are always immediately bound when the library is loaded.)

RTLD_NOW

Handle flag.

If this value is specified or the environment variable LD_BIND_NOW is set to a nonempty string, all undefined symbols in the library are resolved before Fiddle.dlopen returns. If this cannot be done an error is returned.

Public Class Methods

sym(name) click to toggle source

Get the address as an Integer for the function named name. The function is searched via dlsym on RTLD_NEXT.

See man(3) dlsym() for more info.

static VALUE
rb_fiddle_handle_s_sym(VALUE self, VALUE sym)
{
    return fiddle_handle_sym(RTLD_NEXT, StringValueCStr(sym));
}
new(lib = nil, flags = Fiddle::RTLD_LAZY | Fiddle::RTLD_GLOBAL) click to toggle source

Create a new handler that opens library named lib with flags. If no library is specified, RTLD_DEFAULT is used.

static VALUE
rb_fiddle_handle_initialize(int argc, VALUE argv[], VALUE self)
{
    void *ptr;
    struct dl_handle *fiddle_handle;
    VALUE lib, flag;
    char  *clib;
    int   cflag;
    const char *err;

    switch( rb_scan_args(argc, argv, "02", &lib, &flag) ){
      case 0:
        clib = NULL;
        cflag = RTLD_LAZY | RTLD_GLOBAL;
        break;
      case 1:
        clib = NIL_P(lib) ? NULL : StringValuePtr(lib);
        cflag = RTLD_LAZY | RTLD_GLOBAL;
        break;
      case 2:
        clib = NIL_P(lib) ? NULL : StringValuePtr(lib);
        cflag = NUM2INT(flag);
        break;
      default:
        rb_bug("rb_fiddle_handle_new");
    }

    rb_secure(2);

#if defined(_WIN32)
    if( !clib ){
        HANDLE rb_libruby_handle(void);
        ptr = rb_libruby_handle();
    }
    else if( STRCASECMP(clib, "libc") == 0
# ifdef RUBY_COREDLL
             || STRCASECMP(clib, RUBY_COREDLL) == 0
             || STRCASECMP(clib, RUBY_COREDLL".dll") == 0
# endif
        ){
# ifdef _WIN32_WCE
        ptr = dlopen("coredll.dll", cflag);
# else
        ptr = w32_coredll();
# endif
    }
    else
#endif
        ptr = dlopen(clib, cflag);
#if defined(HAVE_DLERROR)
    if( !ptr && (err = dlerror()) ){
        rb_raise(rb_eFiddleError, "%s", err);
    }
#else
    if( !ptr ){
        err = dlerror();
        rb_raise(rb_eFiddleError, "%s", err);
    }
#endif
    TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
    if( fiddle_handle->ptr && fiddle_handle->open && fiddle_handle->enable_close ){
        dlclose(fiddle_handle->ptr);
    }
    fiddle_handle->ptr = ptr;
    fiddle_handle->open = 1;
    fiddle_handle->enable_close = 0;

    if( rb_block_given_p() ){
        rb_ensure(rb_yield, self, rb_fiddle_handle_close, self);
    }

    return Qnil;
}
sym(name) click to toggle source

Get the address as an Integer for the function named name.

static VALUE
rb_fiddle_handle_s_sym(VALUE self, VALUE sym)
{
    return fiddle_handle_sym(RTLD_NEXT, StringValueCStr(sym));
}

Public Instance Methods

sym(name) click to toggle source

Get the address as an Integer for the function named name.

static VALUE
rb_fiddle_handle_sym(VALUE self, VALUE sym)
{
    struct dl_handle *fiddle_handle;

    TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
    if( ! fiddle_handle->open ){
        rb_raise(rb_eFiddleError, "closed handle");
    }

    return fiddle_handle_sym(fiddle_handle->ptr, StringValueCStr(sym));
}
close click to toggle source

Close this handle.

Calling close more than once will raise a Fiddle::DLError exception.

static VALUE
rb_fiddle_handle_close(VALUE self)
{
    struct dl_handle *fiddle_handle;

    TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
    if(fiddle_handle->open) {
        int ret = dlclose(fiddle_handle->ptr);
        fiddle_handle->open = 0;

        /* Check dlclose for successful return value */
        if(ret) {
#if defined(HAVE_DLERROR)
            rb_raise(rb_eFiddleError, "%s", dlerror());
#else
            rb_raise(rb_eFiddleError, "could not close handle");
#endif
        }
        return INT2NUM(ret);
    }
    rb_raise(rb_eFiddleError, "dlclose() called too many times");

    UNREACHABLE;
}
close_enabled? click to toggle source

Returns true if dlclose() will be called when this handle is garbage collected.

See man(3) dlclose() for more info.

static VALUE
rb_fiddle_handle_close_enabled_p(VALUE self)
{
    struct dl_handle *fiddle_handle;

    TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);

    if(fiddle_handle->enable_close) return Qtrue;
    return Qfalse;
}
disable_close click to toggle source

Disable a call to dlclose() when this handle is garbage collected.

static VALUE
rb_fiddle_handle_disable_close(VALUE self)
{
    struct dl_handle *fiddle_handle;

    TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
    fiddle_handle->enable_close = 0;
    return Qnil;
}
enable_close click to toggle source

Enable a call to dlclose() when this handle is garbage collected.

static VALUE
rb_fiddle_handle_enable_close(VALUE self)
{
    struct dl_handle *fiddle_handle;

    TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
    fiddle_handle->enable_close = 1;
    return Qnil;
}
sym(name) click to toggle source

Get the address as an Integer for the function named name.

static VALUE
rb_fiddle_handle_sym(VALUE self, VALUE sym)
{
    struct dl_handle *fiddle_handle;

    TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
    if( ! fiddle_handle->open ){
        rb_raise(rb_eFiddleError, "closed handle");
    }

    return fiddle_handle_sym(fiddle_handle->ptr, StringValueCStr(sym));
}
to_i click to toggle source

Returns the memory address for this handle.

static VALUE
rb_fiddle_handle_to_i(VALUE self)
{
    struct dl_handle *fiddle_handle;

    TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
    return PTR2NUM(fiddle_handle);
}


module Fiddle::Importer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Fiddle::Importer

A DSL that provides the means to dynamically load libraries and build modules around them including calling extern functions within the C library that has been loaded.

Example

require 'fiddle'
require 'fiddle/import'

module LibSum
  extend Fiddle::Importer
  dlload './libsum.so'
  extern 'double sum(double*, int)'
  extern 'double split(double)'
end

In Files

  • ext/fiddle/lib/fiddle/import.rb

Included Modules

  • Fiddle
  • Fiddle::CParser

Public Instance Methods

[](name) click to toggle source

Returns the function mapped to name, that was created by either #extern or #bind

# File ext/fiddle/lib/fiddle/import.rb, line 229
def [](name)
  @func_map[name]
end
bind(signature, *opts, &blk) click to toggle source

Creates a global method from the given C signature using the given opts as bind parameters with the given block.

# File ext/fiddle/lib/fiddle/import.rb, line 185
    def bind(signature, *opts, &blk)
      name, ctype, argtype = parse_signature(signature, @type_alias)
      h = parse_bind_options(opts)
      case h[:callback_type]
      when :bind, nil
        f = bind_function(name, ctype, argtype, h[:call_type], &blk)
      else
        raise(RuntimeError, "unknown callback type: #{h[:callback_type]}")
      end
      @func_map[name] = f
      #define_method(name){|*args,&block| f.call(*args,&block)}
      begin
        /^(.+?):(\d+)/ =~ caller.first
        file, line = $1, $2.to_i
      rescue
        file, line = __FILE__, __LINE__+3
      end
      module_eval("        def #{name}(*args,&block)
          @func_map['#{name}'].call(*args,&block)
        end
", file, line)
      module_function(name)
      f
    end
bind_function(name, ctype, argtype, call_type = nil, &block) click to toggle source

Returns a new closure wrapper for the name function.

  • ctype is the return type of the function

  • argtype is an Array of arguments, passed to the callback function

  • call_type is the abi of the closure

  • block is passed to the callback

See Fiddle::Closure

# File ext/fiddle/lib/fiddle/import.rb, line 305
def bind_function(name, ctype, argtype, call_type = nil, &block)
  abi = CALL_TYPE_TO_ABI[call_type]
  closure = Class.new(Fiddle::Closure) {
    define_method(:call, block)
  }.new(ctype, argtype, abi)

  Function.new(closure, argtype, ctype, abi, name: name)
end
create_value(ty, val=nil) click to toggle source

Creates a class to wrap the C struct with the value ty

See also #struct

# File ext/fiddle/lib/fiddle/import.rb, line 236
def create_value(ty, val=nil)
  s = struct([ty + " value"])
  ptr = s.malloc()
  if( val )
    ptr.value = val
  end
  return ptr
end
Also aliased as: value
dlload(*libs) click to toggle source

Creates an array of handlers for the given libs, can be an instance of Fiddle::Handle, Fiddle::Importer, or will create a new istance of Fiddle::Handle using Fiddle.dlopen

Raises a DLError if the library cannot be loaded.

See Fiddle.dlopen

# File ext/fiddle/lib/fiddle/import.rb, line 72
def dlload(*libs)
  handles = libs.collect{|lib|
    case lib
    when nil
      nil
    when Handle
      lib
    when Importer
      lib.handlers
    else
      begin
        Fiddle.dlopen(lib)
      rescue DLError
        raise(DLError, "can't load #{lib}")
      end
    end
  }.flatten()
  @handler = CompositeHandler.new(handles)
  @func_map = {}
  @type_alias = {}
end
extern(signature, *opts) click to toggle source

Creates a global method from the given C signature.

# File ext/fiddle/lib/fiddle/import.rb, line 161
    def extern(signature, *opts)
      symname, ctype, argtype = parse_signature(signature, @type_alias)
      opt = parse_bind_options(opts)
      f = import_function(symname, ctype, argtype, opt[:call_type])
      name = symname.gsub(/@.+/,'')
      @func_map[name] = f
      # define_method(name){|*args,&block| f.call(*args,&block)}
      begin
        /^(.+?):(\d+)/ =~ caller.first
        file, line = $1, $2.to_i
      rescue
        file, line = __FILE__, __LINE__+3
      end
      module_eval("        def #{name}(*args, &block)
          @func_map['#{name}'].call(*args,&block)
        end
", file, line)
      module_function(name)
      f
    end
handler() click to toggle source

The Fiddle::CompositeHandler instance

Will raise an error if no handlers are open.

# File ext/fiddle/lib/fiddle/import.rb, line 258
def handler
  @handler or raise "call dlload before importing symbols and functions"
end
import_function(name, ctype, argtype, call_type = nil) click to toggle source

Returns a new Fiddle::Function instance at the memory address of the given name function.

Raises a DLError if the name doesn't exist.

  • argtype is an Array of arguments, passed to the name function.

  • ctype is the return type of the function

  • call_type is the ABI of the function

See also Fiddle:Fiddle::Function.new

See Fiddle::CompositeHandler#sym and Fiddle::Handler.sym

# File ext/fiddle/lib/fiddle/import.rb, line 288
def import_function(name, ctype, argtype, call_type = nil)
  addr = handler.sym(name)
  if( !addr )
    raise(DLError, "cannot find the function: #{name}()")
  end
  Function.new(addr, argtype, ctype, CALL_TYPE_TO_ABI[call_type],
               name: name)
end
import_symbol(name) click to toggle source

Returns a new Fiddle::Pointer instance at the memory address of the given name symbol.

Raises a DLError if the name doesn't exist.

See Fiddle::CompositeHandler#sym and Fiddle::Handle.sym

# File ext/fiddle/lib/fiddle/import.rb, line 268
def import_symbol(name)
  addr = handler.sym(name)
  if( !addr )
    raise(DLError, "cannot find the symbol: #{name}")
  end
  Pointer.new(addr)
end
import_value(ty, addr) click to toggle source

Returns a new instance of the C struct with the value ty at the addr address.

# File ext/fiddle/lib/fiddle/import.rb, line 248
def import_value(ty, addr)
  s = struct([ty + " value"])
  ptr = s.new(addr)
  return ptr
end
sizeof(ty) click to toggle source

Returns the sizeof ty, using Fiddle::CParser#parse_ctype to determine the C type and the appropriate Fiddle constant.

# File ext/fiddle/lib/fiddle/import.rb, line 101
def sizeof(ty)
  case ty
  when String
    ty = parse_ctype(ty, @type_alias).abs()
    case ty
    when TYPE_CHAR
      return SIZEOF_CHAR
    when TYPE_SHORT
      return SIZEOF_SHORT
    when TYPE_INT
      return SIZEOF_INT
    when TYPE_LONG
      return SIZEOF_LONG
    when TYPE_LONG_LONG
      return SIZEOF_LONG_LONG
    when TYPE_FLOAT
      return SIZEOF_FLOAT
    when TYPE_DOUBLE
      return SIZEOF_DOUBLE
    when TYPE_VOIDP
      return SIZEOF_VOIDP
    else
      raise(DLError, "unknown type: #{ty}")
    end
  when Class
    if( ty.instance_methods().include?(:to_ptr) )
      return ty.size()
    end
  end
  return Pointer[ty].size()
end
struct(signature) click to toggle source

Creates a class to wrap the C struct described by signature.

MyStruct = struct ['int i', 'char c']
# File ext/fiddle/lib/fiddle/import.rb, line 214
def struct(signature)
  tys, mems = parse_struct_signature(signature, @type_alias)
  Fiddle::CStructBuilder.create(CStruct, tys, mems)
end
typealias(alias_type, orig_type) click to toggle source

Sets the type alias for alias_type as orig_type

# File ext/fiddle/lib/fiddle/import.rb, line 95
def typealias(alias_type, orig_type)
  @type_alias[alias_type] = orig_type
end
union(signature) click to toggle source

Creates a class to wrap the C union described by signature.

MyUnion = union ['int i', 'char c']
# File ext/fiddle/lib/fiddle/import.rb, line 222
def union(signature)
  tys, mems = parse_struct_signature(signature, @type_alias)
  Fiddle::CStructBuilder.create(CUnion, tys, mems)
end
value(ty, val=nil) click to toggle source
Alias for: create_value


class Fiddle::Pointer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fiddle::Pointer

Fiddle::Pointer is a class to handle C pointers

In Files

  • ext/fiddle/closure.c

Parent

Object

Public Class Methods

Fiddle::Pointer[val] → cptr click to toggle source
to_ptr(val) → cptr

Get the underlying pointer for ruby object val and return it as a Fiddle::Pointer object.

static VALUE
rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
{
    VALUE ptr, wrap = val, vptr;

    if (RTEST(rb_obj_is_kind_of(val, rb_cIO))){
        rb_io_t *fptr;
        FILE *fp;
        GetOpenFile(val, fptr);
        fp = rb_io_stdio_file(fptr);
        ptr = rb_fiddle_ptr_new(fp, 0, NULL);
    }
    else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){
        char *str = StringValuePtr(val);
        ptr = rb_fiddle_ptr_new(str, RSTRING_LEN(val), NULL);
    }
    else if ((vptr = rb_check_funcall(val, id_to_ptr, 0, 0)) != Qundef){
        if (rb_obj_is_kind_of(vptr, rb_cPointer)){
            ptr = vptr;
            wrap = 0;
        }
        else{
            rb_raise(rb_eFiddleError, "to_ptr should return a Fiddle::Pointer object");
        }
    }
    else{
        VALUE num = rb_Integer(val);
        if (num == val) wrap = 0;
        ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL);
    }
    OBJ_INFECT(ptr, val);
    if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
    return ptr;
}
Fiddle::Pointer.malloc(size, freefunc = nil) → fiddle pointer instance click to toggle source

Allocate size bytes of memory and associate it with an optional freefunc that will be called when the pointer is garbage collected.

freefunc must be an address pointing to a function or an instance of Fiddle::Function

static VALUE
rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)
{
    VALUE size, sym, obj, wrap = 0;
    long s;
    freefunc_t f;

    switch (rb_scan_args(argc, argv, "11", &size, &sym)) {
      case 1:
        s = NUM2LONG(size);
        f = NULL;
        break;
      case 2:
        s = NUM2LONG(size);
        f = get_freefunc(sym, &wrap);
        break;
      default:
        rb_bug("rb_fiddle_ptr_s_malloc");
    }

    obj = rb_fiddle_ptr_malloc(s,f);
    if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;

    return obj;
}
Fiddle::Pointer.new(address) → fiddle_cptr click to toggle source
new(address, size) → fiddle_cptr
new(address, size, freefunc) → fiddle_cptr

Create a new pointer to address with an optional size and freefunc.

freefunc will be called when the instance is garbage collected.

static VALUE
rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self)
{
    VALUE ptr, sym, size, wrap = 0, funcwrap = 0;
    struct ptr_data *data;
    void *p = NULL;
    freefunc_t f = NULL;
    long s = 0;

    if (rb_scan_args(argc, argv, "12", &ptr, &size, &sym) >= 1) {
        VALUE addrnum = rb_Integer(ptr);
        if (addrnum != ptr) wrap = ptr;
        p = NUM2PTR(addrnum);
    }
    if (argc >= 2) {
        s = NUM2LONG(size);
    }
    if (argc >= 3) {
        f = get_freefunc(sym, &funcwrap);
    }

    if (p) {
        TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
        if (data->ptr && data->free) {
            /* Free previous memory. Use of inappropriate initialize may cause SEGV. */
            (*(data->free))(data->ptr);
        }
        data->wrap[0] = wrap;
        data->wrap[1] = funcwrap;
        data->ptr  = p;
        data->size = s;
        data->free = f;
    }

    return Qnil;
}
Fiddle::Pointer[val] → cptr click to toggle source
to_ptr(val) → cptr

Get the underlying pointer for ruby object val and return it as a Fiddle::Pointer object.

static VALUE
rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
{
    VALUE ptr, wrap = val, vptr;

    if (RTEST(rb_obj_is_kind_of(val, rb_cIO))){
        rb_io_t *fptr;
        FILE *fp;
        GetOpenFile(val, fptr);
        fp = rb_io_stdio_file(fptr);
        ptr = rb_fiddle_ptr_new(fp, 0, NULL);
    }
    else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){
        char *str = StringValuePtr(val);
        ptr = rb_fiddle_ptr_new(str, RSTRING_LEN(val), NULL);
    }
    else if ((vptr = rb_check_funcall(val, id_to_ptr, 0, 0)) != Qundef){
        if (rb_obj_is_kind_of(vptr, rb_cPointer)){
            ptr = vptr;
            wrap = 0;
        }
        else{
            rb_raise(rb_eFiddleError, "to_ptr should return a Fiddle::Pointer object");
        }
    }
    else{
        VALUE num = rb_Integer(val);
        if (num == val) wrap = 0;
        ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL);
    }
    OBJ_INFECT(ptr, val);
    if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
    return ptr;
}

Public Instance Methods

ptr + n → new cptr click to toggle source

Returns a new pointer instance that has been advanced n bytes.

static VALUE
rb_fiddle_ptr_plus(VALUE self, VALUE other)
{
    void *ptr;
    long num, size;

    ptr = rb_fiddle_ptr2cptr(self);
    size = RPTR_DATA(self)->size;
    num = NUM2LONG(other);
    return rb_fiddle_ptr_new((char *)ptr + num, size - num, 0);
}
ptr click to toggle source

Returns a new Fiddle::Pointer instance that is a dereferenced pointer for this pointer.

Analogous to the star operator in C.

static VALUE
rb_fiddle_ptr_ptr(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    return rb_fiddle_ptr_new(*((void**)(data->ptr)),0,0);
}
ptr - n → new cptr click to toggle source

Returns a new pointer instance that has been moved back n bytes.

static VALUE
rb_fiddle_ptr_minus(VALUE self, VALUE other)
{
    void *ptr;
    long num, size;

    ptr = rb_fiddle_ptr2cptr(self);
    size = RPTR_DATA(self)->size;
    num = NUM2LONG(other);
    return rb_fiddle_ptr_new((char *)ptr - num, size + num, 0);
}
ref click to toggle source

Returns a new Fiddle::Pointer instance that is a reference pointer for this pointer.

Analogous to the ampersand operator in C.

static VALUE
rb_fiddle_ptr_ref(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    return rb_fiddle_ptr_new(&(data->ptr),0,0);
}
ptr <=> other → -1, 0, 1, or nil click to toggle source

Returns -1 if less than, 0 if equal to, 1 if greater than other.

Returns nil if ptr cannot be compared to other.

static VALUE
rb_fiddle_ptr_cmp(VALUE self, VALUE other)
{
    void *ptr1, *ptr2;
    SIGNED_VALUE diff;

    if(!rb_obj_is_kind_of(other, rb_cPointer)) return Qnil;

    ptr1 = rb_fiddle_ptr2cptr(self);
    ptr2 = rb_fiddle_ptr2cptr(other);
    diff = (SIGNED_VALUE)ptr1 - (SIGNED_VALUE)ptr2;
    if (!diff) return INT2FIX(0);
    return diff > 0 ? INT2NUM(1) : INT2NUM(-1);
}
ptr == other → true or false click to toggle source
eql?(other) → true or false

Returns true if other wraps the same pointer, otherwise returns false.

static VALUE
rb_fiddle_ptr_eql(VALUE self, VALUE other)
{
    void *ptr1, *ptr2;

    if(!rb_obj_is_kind_of(other, rb_cPointer)) return Qfalse;

    ptr1 = rb_fiddle_ptr2cptr(self);
    ptr2 = rb_fiddle_ptr2cptr(other);

    return ptr1 == ptr2 ? Qtrue : Qfalse;
}
ptr[index] → an_integer click to toggle source
ptr[start, length] → a_string

Returns integer stored at index.

If start and length are given, a string containing the bytes from start of length will be returned.

static VALUE
rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self)
{
    VALUE arg0, arg1;
    VALUE retval = Qnil;
    size_t offset, len;
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    if (!data->ptr) rb_raise(rb_eFiddleError, "NULL pointer dereference");
    switch( rb_scan_args(argc, argv, "11", &arg0, &arg1) ){
      case 1:
        offset = NUM2ULONG(arg0);
        retval = INT2NUM(*((char *)data->ptr + offset));
        break;
      case 2:
        offset = NUM2ULONG(arg0);
        len    = NUM2ULONG(arg1);
        retval = rb_tainted_str_new((char *)data->ptr + offset, len);
        break;
      default:
        rb_bug("rb_fiddle_ptr_aref()");
    }
    return retval;
}
ptr[index] = int → int click to toggle source
ptr[start, length] = string or cptr or addr → string or dl_cptr or addr

Set the value at index to int.

Or, set the memory at start until length with the contents of string, the memory from dl_cptr, or the memory pointed at by the memory address addr.

static VALUE
rb_fiddle_ptr_aset(int argc, VALUE argv[], VALUE self)
{
    VALUE arg0, arg1, arg2;
    VALUE retval = Qnil;
    size_t offset, len;
    void *mem;
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    if (!data->ptr) rb_raise(rb_eFiddleError, "NULL pointer dereference");
    switch( rb_scan_args(argc, argv, "21", &arg0, &arg1, &arg2) ){
      case 2:
        offset = NUM2ULONG(arg0);
        ((char*)data->ptr)[offset] = NUM2UINT(arg1);
        retval = arg1;
        break;
      case 3:
        offset = NUM2ULONG(arg0);
        len    = NUM2ULONG(arg1);
        if (RB_TYPE_P(arg2, T_STRING)) {
            mem = StringValuePtr(arg2);
        }
        else if( rb_obj_is_kind_of(arg2, rb_cPointer) ){
            mem = rb_fiddle_ptr2cptr(arg2);
        }
        else{
            mem    = NUM2PTR(arg2);
        }
        memcpy((char *)data->ptr + offset, mem, len);
        retval = arg2;
        break;
      default:
        rb_bug("rb_fiddle_ptr_aset()");
    }
    return retval;
}
ptr == other → true or false click to toggle source
eql?(other) → true or false

Returns true if other wraps the same pointer, otherwise returns false.

static VALUE
rb_fiddle_ptr_eql(VALUE self, VALUE other)
{
    void *ptr1, *ptr2;

    if(!rb_obj_is_kind_of(other, rb_cPointer)) return Qfalse;

    ptr1 = rb_fiddle_ptr2cptr(self);
    ptr2 = rb_fiddle_ptr2cptr(other);

    return ptr1 == ptr2 ? Qtrue : Qfalse;
}
free → Fiddle::Function click to toggle source

Get the free function for this pointer.

Returns a new instance of Fiddle::Function.

See Fiddle::Function.new

static VALUE
rb_fiddle_ptr_free_get(VALUE self)
{
    struct ptr_data *pdata;
    VALUE address;
    VALUE arg_types;
    VALUE ret_type;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata);

    if (!pdata->free)
        return Qnil;

    address = PTR2NUM(pdata->free);
    ret_type = INT2NUM(TYPE_VOID);
    arg_types = rb_ary_new();
    rb_ary_push(arg_types, INT2NUM(TYPE_VOIDP));

    return rb_fiddle_new_function(address, arg_types, ret_type);
}
free=(function) click to toggle source

Set the free function for this pointer to function in the given Fiddle::Function.

static VALUE
rb_fiddle_ptr_free_set(VALUE self, VALUE val)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    data->free = get_freefunc(val, &data->wrap[1]);

    return Qnil;
}
inspect click to toggle source

Returns a string formatted with an easily readable representation of the internal state of the pointer.

static VALUE
rb_fiddle_ptr_inspect(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    return rb_sprintf("#<%"PRIsVALUE":%p ptr=%p size=%ld free=%p>",
                      RB_OBJ_CLASSNAME(self), data, data->ptr, data->size, data->free);
}
null? click to toggle source

Returns true if this is a null pointer.

static VALUE
rb_fiddle_ptr_null_p(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    return data->ptr ? Qfalse : Qtrue;
}
ptr click to toggle source

Returns a new Fiddle::Pointer instance that is a dereferenced pointer for this pointer.

Analogous to the star operator in C.

static VALUE
rb_fiddle_ptr_ptr(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    return rb_fiddle_ptr_new(*((void**)(data->ptr)),0,0);
}
ref click to toggle source

Returns a new Fiddle::Pointer instance that is a reference pointer for this pointer.

Analogous to the ampersand operator in C.

static VALUE
rb_fiddle_ptr_ref(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    return rb_fiddle_ptr_new(&(data->ptr),0,0);
}
size click to toggle source

Get the size of this pointer.

static VALUE
rb_fiddle_ptr_size_get(VALUE self)
{
    return LONG2NUM(RPTR_DATA(self)->size);
}
size=(size) click to toggle source

Set the size of this pointer to size

static VALUE
rb_fiddle_ptr_size_set(VALUE self, VALUE size)
{
    RPTR_DATA(self)->size = NUM2LONG(size);
    return size;
}
to_i click to toggle source

Returns the integer memory location of this pointer.

static VALUE
rb_fiddle_ptr_to_i(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    return PTR2NUM(data->ptr);
}
to_i click to toggle source

Returns the integer memory location of this pointer.

static VALUE
rb_fiddle_ptr_to_i(VALUE self)
{
    struct ptr_data *data;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    return PTR2NUM(data->ptr);
}
to_s → string click to toggle source
to_s(len) → string

Returns the pointer contents as a string.

When called with no arguments, this method will return the contents until the first NULL byte.

When called with len, a string of len bytes will be returned.

See #to_str

static VALUE
rb_fiddle_ptr_to_s(int argc, VALUE argv[], VALUE self)
{
    struct ptr_data *data;
    VALUE arg1, val;
    int len;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    switch (rb_scan_args(argc, argv, "01", &arg1)) {
      case 0:
        val = rb_tainted_str_new2((char*)(data->ptr));
        break;
      case 1:
        len = NUM2INT(arg1);
        val = rb_tainted_str_new((char*)(data->ptr), len);
        break;
      default:
        rb_bug("rb_fiddle_ptr_to_s");
    }

    return val;
}
to_str → string click to toggle source
to_str(len) → string

Returns the pointer contents as a string.

When called with no arguments, this method will return the contents with the length of this pointer's size.

When called with len, a string of len bytes will be returned.

See #to_s

static VALUE
rb_fiddle_ptr_to_str(int argc, VALUE argv[], VALUE self)
{
    struct ptr_data *data;
    VALUE arg1, val;
    int len;

    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    switch (rb_scan_args(argc, argv, "01", &arg1)) {
      case 0:
        val = rb_tainted_str_new((char*)(data->ptr),data->size);
        break;
      case 1:
        len = NUM2INT(arg1);
        val = rb_tainted_str_new((char*)(data->ptr), len);
        break;
      default:
        rb_bug("rb_fiddle_ptr_to_str");
    }

    return val;
}
to_value click to toggle source

Cast this pointer to a ruby object.

static VALUE
rb_fiddle_ptr_to_value(VALUE self)
{
    struct ptr_data *data;
    TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
    return (VALUE)(data->ptr);
}


module Fiddle::Win32Types - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Fiddle::Win32Types

Adds Windows type aliases to the including class for use with Fiddle::Importer.

The aliases added are:

  • ATOM

  • BOOL

  • BYTE

  • DWORD

  • DWORD32

  • DWORD64

  • HANDLE

  • HDC

  • HINSTANCE

  • HWND

  • LPCSTR

  • LPSTR

  • PBYTE

  • PDWORD

  • PHANDLE

  • PVOID

  • PWORD

  • UCHAR

  • UINT

  • ULONG

  • WORD

In Files

  • ext/fiddle/lib/fiddle/types.rb


class File - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class File

In Files

  • lib/pp.rb

Parent

IO


class File::Stat - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class File::Stat

In Files

  • lib/pp.rb

Parent

Object

Public Instance Methods

pretty_print(q) click to toggle source
# File lib/pp.rb, line 393
def pretty_print(q)
  require 'etc.so'
  q.object_group(self) {
    q.breakable
    q.text sprintf("dev=0x%x", self.dev); q.comma_breakable
    q.text "ino="; q.pp self.ino; q.comma_breakable
    q.group {
      m = self.mode
      q.text sprintf("mode=0%o", m)
      q.breakable
      q.text sprintf("(%s %c%c%c%c%c%c%c%c%c)",
        self.ftype,
        (m & 0400 == 0 ? - : r),
        (m & 0200 == 0 ? - : w),
        (m & 0100 == 0 ? (m & 04000 == 0 ? - : S) :
                         (m & 04000 == 0 ? x : s)),
        (m & 0040 == 0 ? - : r),
        (m & 0020 == 0 ? - : w),
        (m & 0010 == 0 ? (m & 02000 == 0 ? - : S) :
                         (m & 02000 == 0 ? x : s)),
        (m & 0004 == 0 ? - : r),
        (m & 0002 == 0 ? - : w),
        (m & 0001 == 0 ? (m & 01000 == 0 ? - : T) :
                         (m & 01000 == 0 ? x : t)))
    }
    q.comma_breakable
    q.text "nlink="; q.pp self.nlink; q.comma_breakable
    q.group {
      q.text "uid="; q.pp self.uid
      begin
        pw = Etc.getpwuid(self.uid)
      rescue ArgumentError
      end
      if pw
        q.breakable; q.text "(#{pw.name})"
      end
    }
    q.comma_breakable
    q.group {
      q.text "gid="; q.pp self.gid
      begin
        gr = Etc.getgrgid(self.gid)
      rescue ArgumentError
      end
      if gr
        q.breakable; q.text "(#{gr.name})"
      end
    }
    q.comma_breakable
    q.group {
      q.text sprintf("rdev=0x%x", self.rdev)
      q.breakable
      q.text sprintf('(%d, %d)', self.rdev_major, self.rdev_minor)
    }
    q.comma_breakable
    q.text "size="; q.pp self.size; q.comma_breakable
    q.text "blksize="; q.pp self.blksize; q.comma_breakable
    q.text "blocks="; q.pp self.blocks; q.comma_breakable
    q.group {
      t = self.atime
      q.text "atime="; q.pp t
      q.breakable; q.text "(#{t.tv_sec})"
    }
    q.comma_breakable
    q.group {
      t = self.mtime
      q.text "mtime="; q.pp t
      q.breakable; q.text "(#{t.tv_sec})"
    }
    q.comma_breakable
    q.group {
      t = self.ctime
      q.text "ctime="; q.pp t
      q.breakable; q.text "(#{t.tv_sec})"
    }
  }
end


module FileUtils - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module FileUtils

fileutils.rb

Copyright © 2000-2007 Minero Aoki

This program is free software. You can distribute/modify this program under the same terms of ruby.

module FileUtils

Namespace for several file utility methods for copying, moving, removing, etc.

Module Functions

cd(dir, options)
cd(dir, options) {|dir| .... }
pwd()
mkdir(dir, options)
mkdir(list, options)
mkdir_p(dir, options)
mkdir_p(list, options)
rmdir(dir, options)
rmdir(list, options)
ln(old, new, options)
ln(list, destdir, options)
ln_s(old, new, options)
ln_s(list, destdir, options)
ln_sf(src, dest, options)
cp(src, dest, options)
cp(list, dir, options)
cp_r(src, dest, options)
cp_r(list, dir, options)
mv(src, dest, options)
mv(list, dir, options)
rm(list, options)
rm_r(list, options)
rm_rf(list, options)
install(src, dest, mode = <src's>, options)
chmod(mode, list, options)
chmod_R(mode, list, options)
chown(user, group, list, options)
chown_R(user, group, list, options)
touch(list, options)

The options parameter is a hash of options, taken from the list :force, :noop, :preserve, and :verbose. :noop means that no changes are made. The other two are obvious. Each method documents the options that it honours.

All methods that have the concept of a “source” file or directory can take either one file or a list of files in that argument. See the method documentation for examples.

There are some `low level' methods, which do not accept any option:

copy_entry(src, dest, preserve = false, dereference = false)
copy_file(src, dest, preserve = false, dereference = true)
copy_stream(srcstream, deststream)
remove_entry(path, force = false)
remove_entry_secure(path, force = false)
remove_file(path, force = false)
compare_file(path_a, path_b)
compare_stream(stream_a, stream_b)
uptodate?(file, cmp_list)

module FileUtils::Verbose

This module has all methods of FileUtils module, but it outputs messages before acting. This equates to passing the :verbose flag to methods in FileUtils.

module FileUtils::NoWrite

This module has all methods of FileUtils module, but never changes files/directories. This equates to passing the :noop flag to methods in FileUtils.

module FileUtils::DryRun

This module has all methods of FileUtils module, but never changes files/directories. This equates to passing the :noop and :verbose flags to methods in FileUtils.

In Files

  • lib/fileutils.rb
  • lib/rake/file_utils.rb
  • lib/un.rb

Included Modules

  • FileUtils::StreamUtils_

Constants

LN_SUPPORTED
LOW_METHODS
METHODS
RUBY

Path to the currently running Ruby program

Public Class Methods

cd(dir, options = {}) { |dir| ... } click to toggle source

Options: verbose

Changes the current directory to the directory dir.

If this method is called with block, resumes to the old working directory after the block execution finished.

FileUtils.cd('/', :verbose => true)   # chdir and report it

FileUtils.cd('/') do  # chdir
  [...]               # do something
end                   # return to original directory

# File lib/fileutils.rb, line 122
def cd(dir, options = {}, &block) # :yield: dir
  fu_check_options options, OPT_TABLE['cd']
  fu_output_message "cd #{dir}" if options[:verbose]
  Dir.chdir(dir, &block)
  fu_output_message 'cd -' if options[:verbose] and block
end
Also aliased as: chdir
chdir(dir, options = {}) click to toggle source
Alias for: cd
chmod(mode, list, options = {}) click to toggle source

Options: noop verbose

Changes permission bits on the named files (in list) to the bit pattern represented by mode.

mode is the symbolic and absolute mode can be used.

Absolute mode is

FileUtils.chmod 0755, 'somecommand'
FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
FileUtils.chmod 0755, '/usr/bin/ruby', :verbose => true

Symbolic mode is

FileUtils.chmod "u=wrx,go=rx", 'somecommand'
FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb)
FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', :verbose => true
“a”

is user, group, other mask.

“u”

is user's mask.

“g”

is group's mask.

“o”

is other's mask.

“w”

is write permission.

“r”

is read permission.

“x”

is execute permission.

“X”

is execute permission for directories only, must be used in conjunction with “+”

“s”

is uid, gid.

“t”

is sticky bit.

“+”

is added to a class given the specified mode.

“-”

Is removed from a given class given mode.

“=”

Is the exact nature of the class will be given a specified mode.

# File lib/fileutils.rb, line 968
def chmod(mode, list, options = {})
  fu_check_options options, OPT_TABLE['chmod']
  list = fu_list(list)
  fu_output_message sprintf('chmod %s %s', mode_to_s(mode), list.join(' ')) if options[:verbose]
  return if options[:noop]
  list.each do |path|
    Entry_.new(path).chmod(fu_mode(mode, path))
  end
end
chmod_R(mode, list, options = {}) click to toggle source

Options: noop verbose force

Changes permission bits on the named files (in list) to the bit pattern represented by mode.

FileUtils.chmod_R 0700, "/tmp/app.#{$$}"
FileUtils.chmod_R "u=wrx", "/tmp/app.#{$$}"
# File lib/fileutils.rb, line 990
def chmod_R(mode, list, options = {})
  fu_check_options options, OPT_TABLE['chmod_R']
  list = fu_list(list)
  fu_output_message sprintf('chmod -R%s %s %s',
                            (options[:force] ? 'f' : ''),
                            mode_to_s(mode), list.join(' ')) if options[:verbose]
  return if options[:noop]
  list.each do |root|
    Entry_.new(root).traverse do |ent|
      begin
        ent.chmod(fu_mode(mode, ent.path))
      rescue
        raise unless options[:force]
      end
    end
  end
end
chown(user, group, list, options = {}) click to toggle source

Options: noop verbose

Changes owner and group on the named files (in list) to the user user and the group group. user and group may be an ID (Integer/String) or a name (String). If user or group is nil, this method does not change the attribute.

FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true

# File lib/fileutils.rb, line 1023
def chown(user, group, list, options = {})
  fu_check_options options, OPT_TABLE['chown']
  list = fu_list(list)
  fu_output_message sprintf('chown %s %s',
                            (group ? "#{user}:#{group}" : user || ':'),
                            list.join(' ')) if options[:verbose]
  return if options[:noop]
  uid = fu_get_uid(user)
  gid = fu_get_gid(group)
  list.each do |path|
    Entry_.new(path).chown uid, gid
  end
end
chown_R(user, group, list, options = {}) click to toggle source

Options: noop verbose force

Changes owner and group on the named files (in list) to the user user and the group group recursively. user and group may be an ID (Integer/String) or a name (String). If user or group is nil, this method does not change the attribute.

FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', :verbose => true

# File lib/fileutils.rb, line 1052
def chown_R(user, group, list, options = {})
  fu_check_options options, OPT_TABLE['chown_R']
  list = fu_list(list)
  fu_output_message sprintf('chown -R%s %s %s',
                            (options[:force] ? 'f' : ''),
                            (group ? "#{user}:#{group}" : user || ':'),
                            list.join(' ')) if options[:verbose]
  return if options[:noop]
  uid = fu_get_uid(user)
  gid = fu_get_gid(group)
  return unless uid or gid
  list.each do |root|
    Entry_.new(root).traverse do |ent|
      begin
        ent.chown uid, gid
      rescue
        raise unless options[:force]
      end
    end
  end
end
cmp(a, b) click to toggle source
Alias for: compare_file
compare_file(a, b) click to toggle source

Returns true if the contents of a file A and a file B are identical.

FileUtils.compare_file('somefile', 'somefile')  #=> true
FileUtils.compare_file('/bin/cp', '/bin/mv')    #=> maybe false

# File lib/fileutils.rb, line 806
def compare_file(a, b)
  return false unless File.size(a) == File.size(b)
  File.open(a, 'rb') {|fa|
    File.open(b, 'rb') {|fb|
      return compare_stream(fa, fb)
    }
  }
end
Also aliased as: identical?, cmp
compare_stream(a, b) click to toggle source

Returns true if the contents of a stream a and b are identical.

# File lib/fileutils.rb, line 824
def compare_stream(a, b)
  bsize = fu_stream_blksize(a, b)
  sa = ""
  sb = ""
  begin
    a.read(bsize, sa)
    b.read(bsize, sb)
    return true if sa.empty? && sb.empty?
  end while sa == sb
  false
end
copy(src, dest, options = {}) click to toggle source
Alias for: cp
copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) click to toggle source

Copies a file system entry src to dest. If src is a directory, this method copies its contents recursively. This method preserves file types, c.f. symlink, directory… (FIFO, device files and etc. are not supported yet)

Both of src and dest must be a path name. src must exist, dest must not exist.

If preserve is true, this method preserves owner, group, and modified time. Permissions are copied regardless preserve.

If dereference_root is true, this method dereference tree root.

If remove_destination is true, this method removes each destination file before copy.

# File lib/fileutils.rb, line 459
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
  Entry_.new(src, nil, dereference_root).wrap_traverse(proc do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    File.unlink destent.path if remove_destination && File.file?(destent.path)
    ent.copy destent.path
  end, proc do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    ent.copy_metadata destent.path if preserve
  end)
end
copy_file(src, dest, preserve = false, dereference = true) click to toggle source

Copies file contents of src to dest. Both of src and dest must be a path name.

# File lib/fileutils.rb, line 475
def copy_file(src, dest, preserve = false, dereference = true)
  ent = Entry_.new(src, nil, dereference)
  ent.copy_file dest
  ent.copy_metadata dest if preserve
end
copy_stream(src, dest) click to toggle source

Copies stream src to dest. src must respond to read(n) and dest must respond to write(str).

# File lib/fileutils.rb, line 487
def copy_stream(src, dest)
  IO.copy_stream(src, dest)
end
cp(src, dest, options = {}) click to toggle source

Options: preserve noop verbose

Copies a file content src to dest. If dest is a directory, copies src to dest/src.

If src is a list of files, then dest must be a directory.

FileUtils.cp 'eval.c', 'eval.c.org'
FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', :verbose => true
FileUtils.cp 'symlink', 'dest'   # copy content, "dest" is not a symlink

# File lib/fileutils.rb, line 389
def cp(src, dest, options = {})
  fu_check_options options, OPT_TABLE['cp']
  fu_output_message "cp#{options[:preserve] ? ' -p' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  fu_each_src_dest(src, dest) do |s, d|
    copy_file s, d, options[:preserve]
  end
end
Also aliased as: copy
cp_r(src, dest, options = {}) click to toggle source

Options: preserve noop verbose dereference_root remove_destination

Copies src to dest. If src is a directory, this method copies all its contents recursively. If dest is a directory, copies src to dest/src.

src can be a list of files.

# Installing ruby library "mylib" under the site_ruby
FileUtils.rm_r site_ruby + '/mylib', :force
FileUtils.cp_r 'lib/', site_ruby + '/mylib'

# Examples of copying several files to target directory.
FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
FileUtils.cp_r Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop => true, :verbose => true

# If you want to copy all contents of a directory instead of the
# directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
# use following code.
FileUtils.cp_r 'src/.', 'dest'     # cp_r('src', 'dest') makes dest/src,
                                   # but this doesn't.

# File lib/fileutils.rb, line 428
def cp_r(src, dest, options = {})
  fu_check_options options, OPT_TABLE['cp_r']
  fu_output_message "cp -r#{options[:preserve] ? 'p' : ''}#{options[:remove_destination] ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  options = options.dup
  options[:dereference_root] = true unless options.key?(:dereference_root)
  fu_each_src_dest(src, dest) do |s, d|
    copy_entry s, d, options[:preserve], options[:dereference_root], options[:remove_destination]
  end
end
getwd() click to toggle source
Alias for: pwd
identical?(a, b) click to toggle source
Alias for: compare_file
install(src, dest, options = {}) click to toggle source

Options: mode preserve noop verbose

If src is not same as dest, copies it and changes the permission mode to mode. If dest is a directory, destination is dest/src. This method removes destination before copy.

FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true
FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true

# File lib/fileutils.rb, line 847
def install(src, dest, options = {})
  fu_check_options options, OPT_TABLE['install']
  fu_output_message "install -c#{options[:preserve] && ' -p'}#{options[:mode] ? (' -m 0%o' % options[:mode]) : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  fu_each_src_dest(src, dest) do |s, d, st|
    unless File.exist?(d) and compare_file(s, d)
      remove_file d, true
      copy_file s, d
      File.utime st.atime, st.mtime, d if options[:preserve]
      File.chmod options[:mode], d if options[:mode]
    end
  end
end
link(src, dest, options = {}) click to toggle source
Alias for: ln
ln(src, dest, options = {}) click to toggle source

Options: force noop verbose

ln(old, new, options = {})

Creates a hard link new which points to old. If new already exists and it is a directory, creates a link new/old. If new already exists and it is not a directory, raises Errno::EEXIST. But if :force option is set, overwrite new.

FileUtils.ln 'gcc', 'cc', :verbose => true
FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'

ln(list, destdir, options = {})

Creates several hard links in a directory, with each one pointing to the item in list. If destdir is not a directory, raises Errno::ENOTDIR.

include FileUtils
cd '/sbin'
FileUtils.ln %w(cp mv mkdir), '/bin'   # Now /sbin/cp and /bin/cp are linked.
# File lib/fileutils.rb, line 304
def ln(src, dest, options = {})
  fu_check_options options, OPT_TABLE['ln']
  fu_output_message "ln#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  fu_each_src_dest0(src, dest) do |s,d|
    remove_file d, true if options[:force]
    File.link s, d
  end
end
Also aliased as: link
ln_s(src, dest, options = {}) click to toggle source

Options: force noop verbose

ln_s(old, new, options = {})

Creates a symbolic link new which points to old. If new already exists and it is a directory, creates a symbolic link new/old. If new already exists and it is not a directory, raises Errno::EEXIST. But if :force option is set, overwrite new.

FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
FileUtils.ln_s 'verylongsourcefilename.c', 'c', :force => true

ln_s(list, destdir, options = {})

Creates several symbolic links in a directory, with each one pointing to the item in list. If destdir is not a directory, raises Errno::ENOTDIR.

If destdir is not a directory, raises Errno::ENOTDIR.

FileUtils.ln_s Dir.glob('bin/*.rb'), '/home/aamine/bin'
# File lib/fileutils.rb, line 343
def ln_s(src, dest, options = {})
  fu_check_options options, OPT_TABLE['ln_s']
  fu_output_message "ln -s#{options[:force] ? 'f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  fu_each_src_dest0(src, dest) do |s,d|
    remove_file d, true if options[:force]
    File.symlink s, d
  end
end
Also aliased as: symlink
ln_sf(src, dest, options = {}) click to toggle source

Options: noop verbose

Same as

#ln_s(src, dest, :force => true)

# File lib/fileutils.rb, line 366
def ln_sf(src, dest, options = {})
  fu_check_options options, OPT_TABLE['ln_sf']
  options = options.dup
  options[:force] = true
  ln_s src, dest, options
end
makedirs(list, options = {}) click to toggle source
Alias for: mkdir_p
mkdir(list, options = {}) click to toggle source

Options: mode noop verbose

Creates one or more directories.

FileUtils.mkdir 'test'
FileUtils.mkdir %w( tmp data )
FileUtils.mkdir 'notexist', :noop => true  # Does not really create.
FileUtils.mkdir 'tmp', :mode => 0700

# File lib/fileutils.rb, line 167
def mkdir(list, options = {})
  fu_check_options options, OPT_TABLE['mkdir']
  list = fu_list(list)
  fu_output_message "mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose]
  return if options[:noop]

  list.each do |dir|
    fu_mkdir dir, options[:mode]
  end
end
mkdir_p(list, options = {}) click to toggle source

Options: mode noop verbose

Creates a directory and all its parent directories. For example,

FileUtils.mkdir_p '/usr/local/lib/ruby'

causes to make following directories, if it does not exist.

* /usr
* /usr/local
* /usr/local/lib
* /usr/local/lib/ruby

You can pass several directories at a time in a list.

# File lib/fileutils.rb, line 197
def mkdir_p(list, options = {})
  fu_check_options options, OPT_TABLE['mkdir_p']
  list = fu_list(list)
  fu_output_message "mkdir -p #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose]
  return *list if options[:noop]

  list.map {|path| path.chomp(/) }.each do |path|
    # optimize for the most common case
    begin
      fu_mkdir path, options[:mode]
      next
    rescue SystemCallError
      next if File.directory?(path)
    end

    stack = []
    until path == stack.last   # dirname("/")=="/", dirname("C:/")=="C:/"
      stack.push path
      path = File.dirname(path)
    end
    stack.reverse_each do |dir|
      begin
        fu_mkdir dir, options[:mode]
      rescue SystemCallError
        raise unless File.directory?(dir)
      end
    end
  end

  return *list
end
Also aliased as: mkpath, makedirs
mkpath(list, options = {}) click to toggle source
Alias for: mkdir_p
move(src, dest, options = {}) click to toggle source
Alias for: mv
mv(src, dest, options = {}) click to toggle source

Options: force noop verbose

Moves file(s) src to dest. If file and dest exist on the different disk partition, the file is copied then the original file is removed.

FileUtils.mv 'badname.rb', 'goodname.rb'
FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', :force => true  # no error

FileUtils.mv %w(junk.txt dust.txt), '/home/aamine/.trash/'
FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true

# File lib/fileutils.rb, line 504
def mv(src, dest, options = {})
  fu_check_options options, OPT_TABLE['mv']
  fu_output_message "mv#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  fu_each_src_dest(src, dest) do |s, d|
    destent = Entry_.new(d, nil, true)
    begin
      if destent.exist?
        if destent.directory?
          raise Errno::EEXIST, dest
        else
          destent.remove_file if rename_cannot_overwrite_file?
        end
      end
      begin
        File.rename s, d
      rescue Errno::EXDEV
        copy_entry s, d, true
        if options[:secure]
          remove_entry_secure s, options[:force]
        else
          remove_entry s, options[:force]
        end
      end
    rescue SystemCallError
      raise unless options[:force]
    end
  end
end
Also aliased as: move
pwd() click to toggle source

Options: (none)

Returns the name of the current directory.

# File lib/fileutils.rb, line 100
def pwd
  Dir.pwd
end
Also aliased as: getwd
remove(list, options = {}) click to toggle source
Alias for: rm
remove_dir(path, force = false) click to toggle source

Removes a directory dir and its contents recursively. This method ignores StandardError if force is true.

# File lib/fileutils.rb, line 795
def remove_dir(path, force = false)
  remove_entry path, force   # FIXME?? check if it is a directory
end
remove_entry(path, force = false) click to toggle source

This method removes a file system entry path. path might be a regular file, a directory, or something. If path is a directory, remove it recursively.

See also remove_entry_secure.

# File lib/fileutils.rb, line 767
def remove_entry(path, force = false)
  Entry_.new(path).postorder_traverse do |ent|
    begin
      ent.remove
    rescue
      raise unless force
    end
  end
rescue
  raise unless force
end
remove_entry_secure(path, force = false) click to toggle source

This method removes a file system entry path. path shall be a regular file, a directory, or something. If path is a directory, remove it recursively. This method is required to avoid TOCTTOU (time-of-check-to-time-of-use) local security vulnerability of rm_r. rm_r causes security hole when:

* Parent directory is world writable (including /tmp).
* Removing directory tree includes world writable directory.
* The system has symbolic link.

To avoid this security hole, this method applies special preprocess. If path is a directory, this method chown(2) and chmod(2) all removing directories. This requires the current process is the owner of the removing whole directory tree, or is the super user (root).

WARNING: You must ensure that ALL parent directories cannot be moved by other untrusted users. For example, parent directories should not be owned by untrusted users, and should not be world writable except when the sticky bit set.

WARNING: Only the owner of the removing directory tree, or Unix super user (root) should invoke this method. Otherwise this method does not work.

For details of this security vulnerability, see Perl's case:

http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452

For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].

# File lib/fileutils.rb, line 690
def remove_entry_secure(path, force = false)
  unless fu_have_symlink?
    remove_entry path, force
    return
  end
  fullpath = File.expand_path(path)
  st = File.lstat(fullpath)
  unless st.directory?
    File.unlink fullpath
    return
  end
  # is a directory.
  parent_st = File.stat(File.dirname(fullpath))
  unless parent_st.world_writable?
    remove_entry path, force
    return
  end
  unless parent_st.sticky?
    raise ArgumentError, "parent directory is world writable, FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})"
  end
  # freeze tree root
  euid = Process.euid
  File.open(fullpath + '/.') {|f|
    unless fu_stat_identical_entry?(st, f.stat)
      # symlink (TOC-to-TOU attack?)
      File.unlink fullpath
      return
    end
    f.chown euid, -1
    f.chmod 0700
    unless fu_stat_identical_entry?(st, File.lstat(fullpath))
      # TOC-to-TOU attack?
      File.unlink fullpath
      return
    end
  }
  # ---- tree root is frozen ----
  root = Entry_.new(path)
  root.preorder_traverse do |ent|
    if ent.directory?
      ent.chown euid, -1
      ent.chmod 0700
    end
  end
  root.postorder_traverse do |ent|
    begin
      ent.remove
    rescue
      raise unless force
    end
  end
rescue
  raise unless force
end
remove_file(path, force = false) click to toggle source

Removes a file path. This method ignores StandardError if force is true.

# File lib/fileutils.rb, line 784
def remove_file(path, force = false)
  Entry_.new(path).remove_file
rescue
  raise unless force
end
rm(list, options = {}) click to toggle source

Options: force noop verbose

Remove file(s) specified in list. This method cannot remove directories. All StandardErrors are ignored when the :force option is set.

FileUtils.rm %w( junk.txt dust.txt )
FileUtils.rm Dir.glob('*.so')
FileUtils.rm 'NotExistFile', :force => true   # never raises exception

# File lib/fileutils.rb, line 556
def rm(list, options = {})
  fu_check_options options, OPT_TABLE['rm']
  list = fu_list(list)
  fu_output_message "rm#{options[:force] ? ' -f' : ''} #{list.join ' '}" if options[:verbose]
  return if options[:noop]

  list.each do |path|
    remove_file path, options[:force]
  end
end
Also aliased as: remove
rm_f(list, options = {}) click to toggle source

Options: noop verbose

Equivalent to

#rm(list, :force => true)

# File lib/fileutils.rb, line 581
def rm_f(list, options = {})
  fu_check_options options, OPT_TABLE['rm_f']
  options = options.dup
  options[:force] = true
  rm list, options
end
Also aliased as: safe_unlink
rm_r(list, options = {}) click to toggle source

Options: force noop verbose secure

remove files list[0] list[1]… If list[n] is a directory, removes its all contents recursively. This method ignores StandardError when :force option is set.

FileUtils.rm_r Dir.glob('/tmp/*')
FileUtils.rm_r '/', :force => true          #  :-)

WARNING: This method causes local vulnerability if one of parent directories or removing directory tree are world writable (including /tmp, whose permission is 1777), and the current process has strong privilege such as Unix super user (root), and the system has symbolic link. For secure removing, read the documentation of remove_entry_secure carefully, and set :secure option to true. Default is :secure=>false.

NOTE: This method calls remove_entry_secure if :secure option is set. See also remove_entry_secure.

# File lib/fileutils.rb, line 616
def rm_r(list, options = {})
  fu_check_options options, OPT_TABLE['rm_r']
  # options[:secure] = true unless options.key?(:secure)
  list = fu_list(list)
  fu_output_message "rm -r#{options[:force] ? 'f' : ''} #{list.join ' '}" if options[:verbose]
  return if options[:noop]
  list.each do |path|
    if options[:secure]
      remove_entry_secure path, options[:force]
    else
      remove_entry path, options[:force]
    end
  end
end
rm_rf(list, options = {}) click to toggle source

Options: noop verbose secure

Equivalent to

#rm_r(list, :force => true)

WARNING: This method causes local vulnerability. Read the documentation of rm_r first.

# File lib/fileutils.rb, line 644
def rm_rf(list, options = {})
  fu_check_options options, OPT_TABLE['rm_rf']
  options = options.dup
  options[:force] = true
  rm_r list, options
end
Also aliased as: rmtree
rmdir(list, options = {}) click to toggle source

Options: noop, verbose

Removes one or more directories.

FileUtils.rmdir 'somedir'
FileUtils.rmdir %w(somedir anydir otherdir)
# Does not really remove directory; outputs message.
FileUtils.rmdir 'somedir', :verbose => true, :noop => true

# File lib/fileutils.rb, line 260
def rmdir(list, options = {})
  fu_check_options options, OPT_TABLE['rmdir']
  list = fu_list(list)
  parents = options[:parents]
  fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if options[:verbose]
  return if options[:noop]
  list.each do |dir|
    begin
      Dir.rmdir(dir = dir.chomp(/))
      if parents
        until (parent = File.dirname(dir)) == '.' or parent == dir
          Dir.rmdir(dir)
        end
      end
    rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
    end
  end
end
rmtree(list, options = {}) click to toggle source
Alias for: rm_rf
safe_unlink(list, options = {}) click to toggle source
Alias for: rm_f
symlink(src, dest, options = {}) click to toggle source
Alias for: ln_s
touch(list, options = {}) click to toggle source

Options: noop verbose

Updates modification time (mtime) and access time (atime) of file(s) in list. Files are created if they don't exist.

FileUtils.touch 'timestamp'
FileUtils.touch Dir.glob('*.c');  system 'make'
# File lib/fileutils.rb, line 1129
def touch(list, options = {})
  fu_check_options options, OPT_TABLE['touch']
  list = fu_list(list)
  created = nocreate = options[:nocreate]
  t = options[:mtime]
  if options[:verbose]
    fu_output_message "touch #{nocreate ? '-c ' : ''}#{t ? t.strftime('-t %Y%m%d%H%M.%S ') : ''}#{list.join ' '}"
  end
  return if options[:noop]
  list.each do |path|
    created = nocreate
    begin
      File.utime(t, t, path)
    rescue Errno::ENOENT
      raise if created
      File.open(path, 'a') {
        ;
      }
      created = true
      retry if t
    end
  end
end
uptodate?(new, old_list) click to toggle source

Options: (none)

Returns true if newer is newer than all old_list. Non-existent files are older than any file.

FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or \
    system 'make hello.o'
# File lib/fileutils.rb, line 145
def uptodate?(new, old_list)
  return false unless File.exist?(new)
  new_time = File.mtime(new)
  old_list.each do |old|
    if File.exist?(old)
      return false unless new_time > File.mtime(old)
    end
  end
  true
end

Public Instance Methods

ruby(*args,&block) click to toggle source

Run a Ruby interpreter with the given arguments.

Example:

ruby %{-pe '$_.upcase!' <README}
# File lib/rake/file_utils.rb, line 77
def ruby(*args,&block)
  options = (Hash === args.last) ? args.pop : {}
  if args.length > 1 then
    sh(*([RUBY] + args + [options]), &block)
  else
    sh("#{RUBY} #{args.first}", options, &block)
  end
end
safe_ln(*args) click to toggle source

Attempt to do a normal file link, but fall back to a copy if the link fails.

# File lib/rake/file_utils.rb, line 90
def safe_ln(*args)
  unless LN_SUPPORTED[0]
    cp(*args)
  else
    begin
      ln(*args)
    rescue StandardError, NotImplementedError
      LN_SUPPORTED[0] = false
      cp(*args)
    end
  end
end
sh(*cmd, &block) click to toggle source

Run the system command cmd. If multiple arguments are given the command is not run with the shell (same semantics as Kernel::exec and Kernel::system).

Example:

sh %Q{ls -ltr}

sh 'ls', 'file with spaces'

# check exit status after command runs
sh %Q{grep pattern file} do |ok, res|
  if ! ok
    puts "pattern not found (status = #{res.exitstatus})"
  end
end

# File lib/rake/file_utils.rb, line 33
def sh(*cmd, &block)
  options = (Hash === cmd.last) ? cmd.pop : {}
  shell_runner = block_given? ? block : create_shell_runner(cmd)
  set_verbose_option(options)
  options[:noop] ||= Rake::FileUtilsExt.nowrite_flag
  Rake.rake_check_options options, :noop, :verbose
  Rake.rake_output_message cmd.join(" ") if options[:verbose]

  unless options[:noop]
    res = rake_system(*cmd)
    status = $?
    status = PseudoStatus.new(1) if !res && status.nil?
    shell_runner.call(res, status)
  end
end
split_all(path) click to toggle source

Split a file path into individual directory names.

Example:

split_all("a/b/c") =>  ['a', 'b', 'c']

# File lib/rake/file_utils.rb, line 108
def split_all(path)
  head, tail = File.split(path)
  return [tail] if head == '.' || tail == '/'
  return [head, tail] if head == '/'
  return split_all(head) + [tail]
end


module FileUtils::DryRun - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module FileUtils::DryRun

This module has all methods of FileUtils module, but never changes files/directories, with printing message before acting. This equates to passing the :noop and :verbose flag to methods in FileUtils.

In Files

  • lib/fileutils.rb

Included Modules

  • FileUtils
  • FileUtils::LowMethods


module FileUtils::LowMethods - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module FileUtils::LowMethods

In Files

  • lib/fileutils.rb


module FileUtils::NoWrite - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module FileUtils::NoWrite

This module has all methods of FileUtils module, but never changes files/directories. This equates to passing the :noop flag to methods in FileUtils.

In Files

  • lib/fileutils.rb

Included Modules

  • FileUtils
  • FileUtils::LowMethods


module FileUtils::StreamUtils_ - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module FileUtils::StreamUtils_

In Files

  • lib/fileutils.rb


module FileUtils::Verbose - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module FileUtils::Verbose

This module has all methods of FileUtils module, but it outputs messages before acting. This equates to passing the :verbose flag to methods in FileUtils.

In Files

  • lib/fileutils.rb

Included Modules

  • FileUtils


module Find - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Find

The Find module supports the top-down traversal of a set of file paths.

For example, to total the size of all files under your home directory, ignoring anything in a “dot” directory (e.g. $HOME/.ssh):

require 'find'

total_size = 0

Find.find(ENV["HOME"]) do |path|
  if FileTest.directory?(path)
    if File.basename(path)[0] == .
      Find.prune       # Don't look any further into this directory.
    else
      next
    end
  else
    total_size += FileTest.size(path)
  end
end

In Files

  • lib/find.rb

Public Class Methods

find(*paths) { |path| ... } click to toggle source

Calls the associated block with the name of every file and directory listed as arguments, then recursively on their subdirectories, and so on.

Returns an enumerator if no block is given.

See the Find module documentation for an example.

# File lib/find.rb, line 37
def find(*paths) # :yield: path
  block_given? or return enum_for(__method__, *paths)

  paths.collect!{|d| raise Errno::ENOENT unless File.exist?(d); d.dup}
  while file = paths.shift
    catch(:prune) do
      yield file.dup.taint
      begin
        s = File.lstat(file)
      rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
        next
      end
      if s.directory? then
        begin
          fs = Dir.entries(file)
        rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
          next
        end
        fs.sort!
        fs.reverse_each {|f|
          next if f == "." or f == ".."
          f = File.join(file, f)
          paths.unshift f.untaint
        }
      end
    end
  end
end
prune() click to toggle source

Skips the current file or directory, restarting the loop with the next entry. If the current file is a directory, that directory will not be recursively entered. Meaningful only within the block associated with ::find.

See the Find module documentation for an example.

# File lib/find.rb, line 74
def prune
  throw :prune
end


class Fixnum - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Fixnum

When mathn is required, Fixnum's division and exponentiation are enhanced to return more precise values from mathematical expressions.

2/3*3  # => 0
require 'mathn'
2/3*3  # => 2

In Files

  • lib/mathn.rb
  • lib/rational.rb
  • lib/rexml/xpath_parser.rb

Parent

Object

Public Instance Methods

**(other) click to toggle source

Exponentiate by other

# File lib/mathn.rb, line 78
def ** (other)
  if self < 0 && other.round != other
    Complex(self, 0.0) ** other
  else
    power!(other)
  end
end
Also aliased as: power!
dclone() click to toggle source

provides a unified clone operation, for REXML::XPathParser to use across multiple Object types

# File lib/rexml/xpath_parser.rb, line 22
def dclone ; self ; end
power!(other) click to toggle source
Alias for: **


class Float - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Float

When mathn is required, Float is changed to handle Complex numbers.

In Files

  • lib/mathn.rb
  • lib/rexml/xpath_parser.rb
  • ext/bigdecimal/lib/bigdecimal/util.rb

Parent

Numeric

Public Instance Methods

**(other) click to toggle source

Exponentiate by other

# File lib/mathn.rb, line 316
def ** (other)
  if self < 0 && other.round != other
    Complex(self, 0.0) ** other
  else
    power!(other)
  end
end
Also aliased as: power!
dclone() click to toggle source

provides a unified clone operation, for REXML::XPathParser to use across multiple Object types

# File lib/rexml/xpath_parser.rb, line 27
def dclone ; self ; end
power!(other) click to toggle source
Alias for: **
to_d → bigdecimal click to toggle source

Convert flt to a BigDecimal and return it.

require 'bigdecimal'
require 'bigdecimal/util'

0.5.to_d
# => #<BigDecimal:1dc69e0,'0.5E0',9(18)>

# File ext/bigdecimal/lib/bigdecimal/util.rb, line 30
def to_d(precision=nil)
  BigDecimal(self, precision || Float::DIG+1)
end


class Foo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Foo

In Files

  • lib/drb/extserv.rb

Parent

Object


module Forwardable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Forwardable

The Forwardable module provides delegation of specified methods to a designated object, using the methods def_delegator and def_delegators.

For example, say you have a class RecordCollection which contains an array @records. You could provide the lookup method record_number(), which simply calls #[] on the @records array, like this:

class RecordCollection
  extend Forwardable
  def_delegator :@records, :[], :record_number
end

Further, if you wish to provide the methods size, #<<, and map, all of which delegate to @records, this is how you can do it:

class RecordCollection
  # extend Forwardable, but we did that above
  def_delegators :@records, :size, :<<, :map
end
f = Foo.new
f.printf ...
f.gets
f.content_at(1)

If the object isn't a Module and Class, You can too extend Forwardable module.

printer = String.new
printer.extend Forwardable              # prepare object for delegation
printer.def_delegator "STDOUT", "puts"  # add delegation for STDOUT.puts()
printer.puts "Howdy!"

Another example

We want to rely on what has come before obviously, but with delegation we can take just the methods we need and even rename them as appropriate. In many cases this is preferable to inheritance, which gives us the entire old interface, even if much of it isn't needed.

class Queue
  extend Forwardable

  def initialize
    @q = [ ]    # prepare delegate object
  end

  # setup preferred interface, enq() and deq()...
  def_delegator :@q, :push, :enq
  def_delegator :@q, :shift, :deq

  # support some general Array methods that fit Queues well
  def_delegators :@q, :clear, :first, :push, :shift, :size
end

q = Queue.new
q.enq 1, 2, 3, 4, 5
q.push 6

q.shift    # => 1
while q.size > 0
  puts q.deq
end

q.enq "Ruby", "Perl", "Python"
puts q.first
q.clear
puts q.first

This should output:

2
3
4
5
6
Ruby
nil

Notes

Be advised, RDoc will not detect delegated methods.

forwardable.rb provides single-method delegation via the #def_delegator and #def_delegators methods. For full-class delegation via DelegateClass, see delegate.rb.

In Files

  • lib/forwardable.rb

Constants

FORWARDABLE_VERSION

Version of forwardable.rb

Attributes

debug[RW]

If true, __FILE__ will remain in the backtrace in the event an Exception is raised.

Public Instance Methods

def_delegator(accessor, method, ali = method) click to toggle source
Alias for: def_instance_delegator
def_delegators(accessor, *methods) click to toggle source
Alias for: def_instance_delegators
def_instance_delegator(accessor, method, ali = method) click to toggle source

Define method as delegator instance method with an optional alias name ali. Method calls to ali will be delegated to accessor.method.

class MyQueue
  extend Forwardable
  attr_reader :queue
  def initialize
    @queue = []
  end

  def_delegator :@queue, :push, :mypush
end

q = MyQueue.new
q.mypush 42
q.queue    #=> [42]
q.push 23  #=> NoMethodError

# File lib/forwardable.rb, line 167
def def_instance_delegator(accessor, method, ali = method)
  line_no = __LINE__; str = %Q{
    def #{ali}(*args, &block)
      begin
        #{accessor}.__send__(:#{method}, *args, &block)
      rescue Exception
        $@.delete_if{|s| %r"#{Regexp.quote(__FILE__)}"o =~ s} unless Forwardable::debug
        ::Kernel::raise
      end
    end
  }
  # If it's not a class or module, it's an instance
  begin
    module_eval(str, __FILE__, line_no)
  rescue
    instance_eval(str, __FILE__, line_no)
  end

end
Also aliased as: def_delegator
def_instance_delegators(accessor, *methods) click to toggle source

Shortcut for defining multiple delegator methods, but with no provision for using a different name. The following two code samples have the same effect:

def_delegators :@records, :size, :<<, :map

def_delegator :@records, :size
def_delegator :@records, :<<
def_delegator :@records, :map
# File lib/forwardable.rb, line 140
def def_instance_delegators(accessor, *methods)
  methods.delete("__send__")
  methods.delete("__id__")
  for method in methods
    def_instance_delegator(accessor, method)
  end
end
Also aliased as: def_delegators
delegate(hash) click to toggle source
Alias for: instance_delegate
delegate method → accessor click to toggle source
delegate [method, method, ...] → accessor

Takes a hash as its argument. The key is a symbol or an array of symbols. These symbols correspond to method names. The value is the accessor to which the methods will be delegated.

# File lib/forwardable.rb, line 120
def instance_delegate(hash)
  hash.each{ |methods, accessor|
    methods = [methods] unless methods.respond_to?(:each)
    methods.each{ |method|
      def_instance_delegator(accessor, method)
    }
  }
end
Also aliased as: delegate


class GDBM - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class GDBM

Summary

Ruby extension for GNU dbm (gdbm) – a simple database engine for storing key-value pairs on disk.

Description

GNU dbm is a library for simple databases. A database is a file that stores key-value pairs. Gdbm allows the user to store, retrieve, and delete data by key. It furthermore allows a non-sorted traversal of all key-value pairs. A gdbm database thus provides the same functionality as a hash. As with objects of the Hash class, elements can be accessed with []. Furthermore, GDBM mixes in the Enumerable module, thus providing convenient methods such as find, collect, map, etc.

A process is allowed to open several different databases at the same time. A process can open a database as a “reader” or a “writer”. Whereas a reader has only read-access to the database, a writer has read- and write-access. A database can be accessed either by any number of readers or by exactly one writer at the same time.

Examples

  1. Opening/creating a database, and filling it with some entries:

    require 'gdbm'

gdbm = GDBM.new("fruitstore.db")
gdbm["ananas"]    = "3"
gdbm["banana"]    = "8"
gdbm["cranberry"] = "4909"
gdbm.close

  2. Reading out a database:

    require 'gdbm'

gdbm = GDBM.new("fruitstore.db")
gdbm.each_pair do |key, value|
  print "#{key}: #{value}\n"
end
gdbm.close

    produces

    banana: 8
ananas: 3
cranberry: 4909

Links

  • www.gnu.org/software/gdbm/

In Files

  • ext/gdbm/gdbm.c

Parent

Object

Included Modules

  • Enumerable

Constants

FAST

flag for new and open. this flag is obsolete for gdbm >= 1.8

NEWDB

open database as a writer; overwrite any existing databases

NOLOCK

flag for new and open

READER

open database as a reader

SYNC

flag for new and open. only for gdbm >= 1.8

VERSION

version of the gdbm library

WRCREAT

open database as a writer; if the database does not exist, create a new one

WRITER

open database as a writer

Public Class Methods

new(filename, mode = 0666, flags = nil) click to toggle source

Creates a new GDBM instance by opening a gdbm file named filename. If the file does not exist, a new file with file mode mode will be created. flags may be one of the following:

  • READER - open as a reader

  • WRITER - open as a writer

  • WRCREAT - open as a writer; if the database does not exist, create a new one

  • NEWDB - open as a writer; overwrite any existing databases

The values WRITER, WRCREAT and NEWDB may be combined with the following values by bitwise or:

  • SYNC - cause all database operations to be synchronized to the disk

  • NOLOCK - do not lock the database file

If no flags are specified, the GDBM object will try to open the database file as a writer and will create it if it does not already exist (cf. flag WRCREAT). If this fails (for instance, if another process has already opened the database as a reader), it will try to open the database file as a reader (cf. flag READER).

static VALUE
fgdbm_initialize(int argc, VALUE *argv, VALUE obj)
{
    VALUE file, vmode, vflags;
    GDBM_FILE dbm;
    struct dbmdata *dbmp;
    int mode, flags = 0;

    if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
        mode = 0666;            /* default value */
    }
    else if (NIL_P(vmode)) {
        mode = -1;              /* return nil if DB does not exist */
    }
    else {
        mode = NUM2INT(vmode);
    }

    if (!NIL_P(vflags))
        flags = NUM2INT(vflags);

    SafeStringValue(file);

#ifdef GDBM_CLOEXEC
    /* GDBM_CLOEXEC is available since gdbm 1.10. */
    flags |= GDBM_CLOEXEC;
#endif

    if (flags & RUBY_GDBM_RW_BIT) {
        flags &= ~RUBY_GDBM_RW_BIT;
        dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
                        flags, mode, MY_FATAL_FUNC);
    }
    else {
        dbm = 0;
        if (mode >= 0)
            dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
                            GDBM_WRCREAT|flags, mode, MY_FATAL_FUNC);
        if (!dbm)
            dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
                            GDBM_WRITER|flags, 0, MY_FATAL_FUNC);
        if (!dbm)
            dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
                            GDBM_READER|flags, 0, MY_FATAL_FUNC);
    }

    if (dbm) {
        rb_fd_fix_cloexec(gdbm_fdesc(dbm));
    }

    if (!dbm) {
        if (mode == -1) return Qnil;

        if (gdbm_errno == GDBM_FILE_OPEN_ERROR ||
            gdbm_errno == GDBM_CANT_BE_READER ||
            gdbm_errno == GDBM_CANT_BE_WRITER)
            rb_sys_fail_str(file);
        else
            rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }

    dbmp = ALLOC(struct dbmdata);
    free_dbm(DATA_PTR(obj));
    DATA_PTR(obj) = dbmp;
    dbmp->di_dbm = dbm;
    dbmp->di_size = -1;

    return obj;
}
open(filename, mode = 0666, flags = nil) click to toggle source
open(filename, mode = 0666, flags = nil) { |gdbm| ... }

If called without a block, this is synonymous to ::new. If a block is given, the new GDBM instance will be passed to the block as a parameter, and the corresponding database file will be closed after the execution of the block code has been finished.

Example for an open call with a block:

require 'gdbm'
GDBM.open("fruitstore.db") do |gdbm|
  gdbm.each_pair do |key, value|
    print "#{key}: #{value}\n"
  end
end

static VALUE
fgdbm_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);

    if (NIL_P(fgdbm_initialize(argc, argv, obj))) {
        return Qnil;
    }

    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, obj, fgdbm_close, obj);
    }

    return obj;
}

Public Instance Methods

gdbm[key] → value click to toggle source

Retrieves the value corresponding to key.

static VALUE
fgdbm_aref(VALUE obj, VALUE keystr)
{
    return rb_gdbm_fetch3(obj, keystr);
}
gdbm[key]= value → value click to toggle source
store(key, value) → value

Associates the value value with the specified key.

static VALUE
fgdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;

    rb_gdbm_modify(obj);
    StringValue(keystr);
    StringValue(valstr);

    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LENINT(keystr);

    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LENINT(valstr);

    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;
    if (gdbm_store(dbm, key, val, GDBM_REPLACE)) {
        if (errno == EPERM) rb_sys_fail(0);
        rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }

    return valstr;
}
cachesize = size → size click to toggle source

Sets the size of the internal bucket cache to size.

static VALUE
fgdbm_set_cachesize(VALUE obj, VALUE val)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    int optval;

    GetDBM2(obj, dbmp, dbm);
    optval = FIX2INT(val);
    if (gdbm_setopt(dbm, GDBM_CACHESIZE, &optval, sizeof(optval)) == -1) {
        rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }
    return val;
}
clear → gdbm click to toggle source

Removes all the key-value pairs within gdbm.

static VALUE
fgdbm_clear(VALUE obj)
{
    datum key, nextkey;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;

    rb_gdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;

#if 0
    while (key = gdbm_firstkey(dbm), key.dptr) {
        if (gdbm_delete(dbm, key)) {
            free(key.dptr);
            rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
        }
        free(key.dptr);
    }
#else
    while (key = gdbm_firstkey(dbm), key.dptr) {
        for (; key.dptr; key = nextkey) {
            nextkey = gdbm_nextkey(dbm, key);
            if (gdbm_delete(dbm, key)) {
                free(key.dptr);
                if (nextkey.dptr) free(nextkey.dptr);
                rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
            }
            free(key.dptr);
        }
    }
#endif
    dbmp->di_size = 0;

    return obj;
}
close → nil click to toggle source

Closes the associated database file.

static VALUE
fgdbm_close(VALUE obj)
{
    struct dbmdata *dbmp;

    GetDBM(obj, dbmp);
    gdbm_close(dbmp->di_dbm);
    dbmp->di_dbm = 0;

    return Qnil;
}
closed? → true or false click to toggle source

Returns true if the associated database file has been closed.

static VALUE
fgdbm_closed(VALUE obj)
{
    struct dbmdata *dbmp;

    Data_Get_Struct(obj, struct dbmdata, dbmp);
    if (dbmp == 0)
        return Qtrue;
    if (dbmp->di_dbm == 0)
        return Qtrue;

    return Qfalse;
}
delete(key) → value or nil click to toggle source

Removes the key-value-pair with the specified key from this database and returns the corresponding value. Returns nil if the database is empty.

static VALUE
fgdbm_delete(VALUE obj, VALUE keystr)
{
    VALUE valstr;

    valstr = fgdbm_fetch(obj, keystr, Qnil);
    rb_gdbm_delete(obj, keystr);
    return valstr;
}
delete_if { |key, value| block } → gdbm click to toggle source
reject! { |key, value| block } → gdbm

Deletes every key-value pair from gdbm for which block evaluates to true.

static VALUE
fgdbm_delete_if(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_tmp_new(0);
    int i, status = 0, n;

    rb_gdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    n = dbmp->di_size;
    dbmp->di_size = -1;

    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        OBJ_FREEZE(keystr);
        valstr = rb_gdbm_fetch2(dbm, keystr);
        ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
        if (status != 0) break;
        if (RTEST(ret)) rb_ary_push(ary, keystr);
        GetDBM2(obj, dbmp, dbm);
    }

    for (i = 0; i < RARRAY_LEN(ary); i++)
        rb_gdbm_delete(obj, RARRAY_PTR(ary)[i]);
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - (int)RARRAY_LEN(ary);
    rb_ary_clear(ary);

    return obj;
}
each_pair { |key, value| block } → gdbm click to toggle source

Executes block for each key in the database, passing the key and the correspoding value as a parameter.

static VALUE
fgdbm_each_pair(VALUE obj)
{
    GDBM_FILE dbm;
    struct dbmdata *dbmp;
    VALUE keystr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_yield(rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr)));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}
each_key { |key| block } → gdbm click to toggle source

Executes block for each key in the database, passing the key as a parameter.

static VALUE
fgdbm_each_key(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_yield(keystr);
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}
each_pair { |key, value| block } → gdbm click to toggle source

Executes block for each key in the database, passing the key and the correspoding value as a parameter.

static VALUE
fgdbm_each_pair(VALUE obj)
{
    GDBM_FILE dbm;
    struct dbmdata *dbmp;
    VALUE keystr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_yield(rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr)));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}
each_value { |value| block } → gdbm click to toggle source

Executes block for each key in the database, passing the corresponding value as a parameter.

static VALUE
fgdbm_each_value(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_yield(rb_gdbm_fetch2(dbm, keystr));
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}
empty? → true or false click to toggle source

Returns true if the database is empty.

static VALUE
fgdbm_empty_p(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;

    GetDBM(obj, dbmp);
    if (dbmp->di_size < 0) {
        dbm = dbmp->di_dbm;

        key = gdbm_firstkey(dbm);
        if (key.dptr) {
            free(key.dptr);
            return Qfalse;
        }
        return Qtrue;
    }

    if (dbmp->di_size == 0) return Qtrue;
    return Qfalse;
}
fastmode = boolean → boolean click to toggle source

Turns the database's fast mode on or off. If fast mode is turned on, gdbm does not wait for writes to be flushed to the disk before continuing.

This option is obsolete for gdbm >= 1.8 since fast mode is turned on by default. See also: syncmode=

static VALUE
fgdbm_set_fastmode(VALUE obj, VALUE val)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    int optval;

    GetDBM2(obj, dbmp, dbm);
    optval = 0;
    if (RTEST(val))
        optval = 1;

    if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval, sizeof(optval)) == -1) {
        rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }
    return val;
}
fetch(key [, default]) → value click to toggle source

Retrieves the value corresponding to key. If there is no value associated with key, default will be returned instead.

static VALUE
fgdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
{
    VALUE keystr, valstr, ifnone;

    rb_scan_args(argc, argv, "11", &keystr, &ifnone);
    valstr = fgdbm_fetch(obj, keystr, ifnone);
    if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
        rb_raise(rb_eIndexError, "key not found");

    return valstr;
}
has_key?(k) → true or false click to toggle source
key?(k) → true or false

Returns true if the given key k exists within the database. Returns false otherwise.

static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    long len;

    StringValue(keystr);
    len = RSTRING_LENINT(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (int)len;

    GetDBM2(obj, dbmp, dbm);
    if (gdbm_exists(dbm, key))
        return Qtrue;
    return Qfalse;
}
has_value?(v) → true or false click to toggle source
value?(v) → true or false

Returns true if the given value v exists within the database. Returns false otherwise.

static VALUE
fgdbm_has_value(VALUE obj, VALUE valstr)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr2;

    StringValue(valstr);
    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        valstr2 = rb_gdbm_fetch2(dbm, keystr);

        if (!NIL_P(valstr2) &&
            (int)RSTRING_LEN(valstr) == (int)RSTRING_LEN(valstr2) &&
            memcmp(RSTRING_PTR(valstr), RSTRING_PTR(valstr2),
                   (int)RSTRING_LEN(valstr)) == 0) {
            return Qtrue;
        }
    }
    return Qfalse;
}
has_key?(k) → true or false click to toggle source
key?(k) → true or false

Returns true if the given key k exists within the database. Returns false otherwise.

static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    long len;

    StringValue(keystr);
    len = RSTRING_LENINT(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (int)len;

    GetDBM2(obj, dbmp, dbm);
    if (gdbm_exists(dbm, key))
        return Qtrue;
    return Qfalse;
}
invert → hash click to toggle source

Returns a hash created by using gdbm's values as keys, and the keys as values.

static VALUE
fgdbm_invert(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr;
    VALUE hash = rb_hash_new();

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {
        valstr = rb_gdbm_fetch2(dbm, keystr);

        rb_hash_aset(hash, valstr, keystr);
    }
    return hash;
}
key(value) → key click to toggle source

Returns the key for a given value. If several keys may map to the same value, the key that is found first will be returned.

static VALUE
fgdbm_key(VALUE obj, VALUE valstr)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr2;

    StringValue(valstr);
    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        valstr2 = rb_gdbm_fetch2(dbm, keystr);
        if (!NIL_P(valstr2) &&
            (int)RSTRING_LEN(valstr) == (int)RSTRING_LEN(valstr2) &&
            memcmp(RSTRING_PTR(valstr), RSTRING_PTR(valstr2),
                   (int)RSTRING_LEN(valstr)) == 0) {
            return keystr;
        }
    }
    return Qnil;
}
has_key?(k) → true or false click to toggle source
key?(k) → true or false

Returns true if the given key k exists within the database. Returns false otherwise.

static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    long len;

    StringValue(keystr);
    len = RSTRING_LENINT(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (int)len;

    GetDBM2(obj, dbmp, dbm);
    if (gdbm_exists(dbm, key))
        return Qtrue;
    return Qfalse;
}
keys → array click to toggle source

Returns an array of all keys of this database.

static VALUE
fgdbm_keys(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_ary_push(ary, keystr);
    }

    return ary;
}
length → fixnum click to toggle source
size → fixnum

Returns the number of key-value pairs in this database.

static VALUE
fgdbm_length(VALUE obj)
{
    datum key, nextkey;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    int i = 0;

    GetDBM2(obj, dbmp, dbm);
    if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);

    for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
        nextkey = gdbm_nextkey(dbm, key);
        free(key.dptr);
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}
has_key?(k) → true or false click to toggle source
key?(k) → true or false

Returns true if the given key k exists within the database. Returns false otherwise.

static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    long len;

    StringValue(keystr);
    len = RSTRING_LENINT(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (int)len;

    GetDBM2(obj, dbmp, dbm);
    if (gdbm_exists(dbm, key))
        return Qtrue;
    return Qfalse;
}
reject { |key, value| block } → hash click to toggle source

Returns a hash copy of gdbm where all key-value pairs from gdbm for which block evaluates to true are removed. See also: delete_if

static VALUE
fgdbm_reject(VALUE obj)
{
    return rb_hash_delete_if(fgdbm_to_hash(obj));
}
delete_if { |key, value| block } → gdbm click to toggle source
reject! { |key, value| block } → gdbm

Deletes every key-value pair from gdbm for which block evaluates to true.

static VALUE
fgdbm_delete_if(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_tmp_new(0);
    int i, status = 0, n;

    rb_gdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    n = dbmp->di_size;
    dbmp->di_size = -1;

    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        OBJ_FREEZE(keystr);
        valstr = rb_gdbm_fetch2(dbm, keystr);
        ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
        if (status != 0) break;
        if (RTEST(ret)) rb_ary_push(ary, keystr);
        GetDBM2(obj, dbmp, dbm);
    }

    for (i = 0; i < RARRAY_LEN(ary); i++)
        rb_gdbm_delete(obj, RARRAY_PTR(ary)[i]);
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - (int)RARRAY_LEN(ary);
    rb_ary_clear(ary);

    return obj;
}
reorganize → gdbm click to toggle source

Reorganizes the database file. This operation removes reserved space of elements that have already been deleted. It is only useful after a lot of deletions in the database.

static VALUE
fgdbm_reorganize(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;

    rb_gdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    gdbm_reorganize(dbm);
    rb_fd_fix_cloexec(gdbm_fdesc(dbm));
    return obj;
}
replace(other) → gdbm click to toggle source

Replaces the content of gdbm with the key-value pairs of other. other must have an #each_pair method.

static VALUE
fgdbm_replace(VALUE obj, VALUE other)
{
    fgdbm_clear(obj);
    rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
    return obj;
}
select { |key, value| block } → array click to toggle source

Returns a new array of all key-value pairs of the database for which block evaluates to true.

static VALUE
fgdbm_select(VALUE obj)
{
    VALUE new = rb_ary_new();
    GDBM_FILE dbm;
    struct dbmdata *dbmp;
    VALUE keystr;

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {
        VALUE assoc = rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr));
        VALUE v = rb_yield(assoc);

        if (RTEST(v)) {
            rb_ary_push(new, assoc);
        }
        GetDBM2(obj, dbmp, dbm);
    }

    return new;
}
shift → (key, value) or nil click to toggle source

Removes a key-value-pair from this database and returns it as a two-item array [ key, value ]. Returns nil if the database is empty.

static VALUE
fgdbm_shift(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr;

    rb_gdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    keystr = rb_gdbm_firstkey(dbm);
    if (NIL_P(keystr)) return Qnil;
    valstr = rb_gdbm_fetch2(dbm, keystr);
    rb_gdbm_delete(obj, keystr);

    return rb_assoc_new(keystr, valstr);
}
length → fixnum click to toggle source
size → fixnum

Returns the number of key-value pairs in this database.

static VALUE
fgdbm_length(VALUE obj)
{
    datum key, nextkey;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    int i = 0;

    GetDBM2(obj, dbmp, dbm);
    if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);

    for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
        nextkey = gdbm_nextkey(dbm, key);
        free(key.dptr);
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}
gdbm[key]= value → value click to toggle source
store(key, value) → value

Associates the value value with the specified key.

static VALUE
fgdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;

    rb_gdbm_modify(obj);
    StringValue(keystr);
    StringValue(valstr);

    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LENINT(keystr);

    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LENINT(valstr);

    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;
    if (gdbm_store(dbm, key, val, GDBM_REPLACE)) {
        if (errno == EPERM) rb_sys_fail(0);
        rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }

    return valstr;
}
sync → gdbm click to toggle source

Unless the gdbm object has been opened with the SYNC flag, it is not guarenteed that database modification operations are immediately applied to the database file. This method ensures that all recent modifications to the database are written to the file. Blocks until all writing operations to the disk have been finished.

static VALUE
fgdbm_sync(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;

    rb_gdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    gdbm_sync(dbm);
    return obj;
}
syncmode = boolean → boolean click to toggle source

Turns the database's synchronization mode on or off. If the synchronization mode is turned on, the database's in-memory state will be synchronized to disk after every database modification operation. If the synchronization mode is turned off, GDBM does not wait for writes to be flushed to the disk before continuing.

This option is only available for gdbm >= 1.8 where syncmode is turned off by default. See also: fastmode=

static VALUE
fgdbm_set_syncmode(VALUE obj, VALUE val)
{
#if !defined(GDBM_SYNCMODE)
    fgdbm_set_fastmode(obj, RTEST(val) ? Qfalse : Qtrue);
    return val;
#else
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    int optval;

    GetDBM2(obj, dbmp, dbm);
    optval = 0;
    if (RTEST(val))
        optval = 1;

    if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval, sizeof(optval)) == -1) {
        rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }
    return val;
#endif
}
to_a → array click to toggle source

Returns an array of all key-value pairs contained in the database.

static VALUE
fgdbm_to_a(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_ary_push(ary, rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr)));
    }

    return ary;
}
to_hash → hash click to toggle source

Returns a hash of all key-value pairs contained in the database.

static VALUE
fgdbm_to_hash(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, hash;

    GetDBM2(obj, dbmp, dbm);
    hash = rb_hash_new();
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_hash_aset(hash, keystr, rb_gdbm_fetch2(dbm, keystr));
    }

    return hash;
}
update(other) → gdbm click to toggle source

Adds the key-value pairs of other to gdbm, overwriting entries with duplicate keys with those from other. other must have an #each_pair method.

static VALUE
fgdbm_update(VALUE obj, VALUE other)
{
    rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
    return obj;
}
has_value?(v) → true or false click to toggle source
value?(v) → true or false

Returns true if the given value v exists within the database. Returns false otherwise.

static VALUE
fgdbm_has_value(VALUE obj, VALUE valstr)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr2;

    StringValue(valstr);
    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        valstr2 = rb_gdbm_fetch2(dbm, keystr);

        if (!NIL_P(valstr2) &&
            (int)RSTRING_LEN(valstr) == (int)RSTRING_LEN(valstr2) &&
            memcmp(RSTRING_PTR(valstr), RSTRING_PTR(valstr2),
                   (int)RSTRING_LEN(valstr)) == 0) {
            return Qtrue;
        }
    }
    return Qfalse;
}
values → array click to toggle source

Returns an array of all values of this database.

static VALUE
fgdbm_values(VALUE obj)
{
    datum key, nextkey;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE valstr, ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
        nextkey = gdbm_nextkey(dbm, key);
        valstr = rb_gdbm_fetch(dbm, key);
        free(key.dptr);
        rb_ary_push(ary, valstr);
    }

    return ary;
}
values_at(key, ...) → array click to toggle source

Returns an array of the values associated with each specified key.

static VALUE
fgdbm_values_at(int argc, VALUE *argv, VALUE obj)
{
    VALUE new = rb_ary_new2(argc);
    int i;

    for (i=0; i<argc; i++) {
        rb_ary_push(new, rb_gdbm_fetch3(obj, argv[i]));
    }

    return new;
}


class GDBMError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class GDBMError

In Files

  • ext/gdbm/gdbm.c

Parent

StandardError


class GDBMFatalError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class GDBMFatalError

In Files

  • ext/gdbm/gdbm.c

Parent

Exception


class GServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class GServer

GServer implements a generic server, featuring thread pool management, simple logging, and multi-server management. See HttpServer in xmlrpc/httpserver.rb in the Ruby standard library for an example of GServer in action.

Any kind of application-level server can be implemented using this class. It accepts multiple simultaneous connections from clients, up to an optional maximum number. Several services (i.e. one service per TCP port) can be run simultaneously, and stopped at any time through the class method GServer.stop(port). All the threading issues are handled, saving you the effort. All events are optionally logged, but you can provide your own event handlers if you wish.

Example

Using GServer is simple. Below we implement a simple time server, run it, query it, and shut it down. Try this code in irb:

require 'gserver'

#
# A server that returns the time in seconds since 1970.
#
class TimeServer < GServer
  def initialize(port=10001, *args)
    super(port, *args)
  end
  def serve(io)
    io.puts(Time.now.to_i)
  end
end

# Run the server with logging enabled (it's a separate thread).
server = TimeServer.new
server.audit = true                  # Turn logging on.
server.start

# *** Now point your browser to http://localhost:10001 to see it working ***

# See if it's still running.
GServer.in_service?(10001)           # -> true
server.stopped?                      # -> false

# Shut the server down gracefully.
server.shutdown

# Alternatively, stop it immediately.
GServer.stop(10001)
# or, of course, "server.stop".

All the business of accepting connections and exception handling is taken care of. All we have to do is implement the method that actually serves the client.

Advanced

As the example above shows, the way to use GServer is to subclass it to create a specific server, overriding the serve method. You can override other methods as well if you wish, perhaps to collect statistics, or emit more detailed logging.

  • connecting

  • disconnecting

  • starting

  • stopping

The above methods are only called if auditing is enabled, via audit=.

You can also override log and error if, for example, you wish to use a more sophisticated logging system.

In Files

  • lib/gserver.rb

Parent

Object

Constants

DEFAULT_HOST

Attributes

audit[RW]

Set to true to cause the callbacks connecting, disconnecting, starting, and stopping to be called during the server's lifecycle

debug[RW]

Set to true to show more detailed logging

host[R]

Host on which to bind, as a String

maxConnections[R]

Maximum number of connections to accept at a time, as a FixNum

port[R]

Port on which to listen, as a FixNum

stdlog[RW]

IO Device on which log messages should be written

Public Class Methods

in_service?(port, host = DEFAULT_HOST) click to toggle source

Check if a server is running on the given port and host

port

port, as a FixNum, of the server to check

host

host on which to find the server to check

Returns true if a server is running on that port and host.

# File lib/gserver.rb, line 109
def GServer.in_service?(port, host = DEFAULT_HOST)
  @@services.has_key?(host) and
    @@services[host].has_key?(port)
end
new(port, host = DEFAULT_HOST, maxConnections = 4, stdlog = $stderr, audit = false, debug = false) click to toggle source

Create a new server

port

the port, as a FixNum, on which to listen

host

the host to bind to

maxConnections

the maximum number of simultaneous connections to accept

stdlog

IO device on which to log messages

audit

if true, lifecycle callbacks will be called. See audit

debug

if true, error messages are logged. See debug

# File lib/gserver.rb, line 222
def initialize(port, host = DEFAULT_HOST, maxConnections = 4,
  stdlog = $stderr, audit = false, debug = false)
  @tcpServerThread = nil
  @port = port
  @host = host
  @maxConnections = maxConnections
  @connections = []
  @connectionsMutex = Mutex.new
  @connectionsCV = ConditionVariable.new
  @stdlog = stdlog
  @audit = audit
  @debug = debug
end
stop(port, host = DEFAULT_HOST) click to toggle source

Stop the server running on the given port, bound to the given host

port

port, as a FixNum, of the server to stop

host

host on which to find the server to stop

# File lib/gserver.rb, line 97
def GServer.stop(port, host = DEFAULT_HOST)
  @@servicesMutex.synchronize {
    @@services[host][port].stop
  }
end

Public Instance Methods

connections() click to toggle source

Return the current number of connected clients

# File lib/gserver.rb, line 134
def connections
  @connections.size
end
join() click to toggle source

Join with the server thread

# File lib/gserver.rb, line 139
def join
  @tcpServerThread.join if @tcpServerThread
end
serve(io) click to toggle source
# File lib/gserver.rb, line 87
def serve(io)
end
shutdown() click to toggle source

Schedule a shutdown for the server

# File lib/gserver.rb, line 129
def shutdown
  @shutdown = true
end
start(maxConnections = -1) click to toggle source

Start the server if it isn't already running

maxConnections

override maxConnections given to the constructor. A negative value indicates that the value from the constructor should be used.

# File lib/gserver.rb, line 241
def start(maxConnections = -1)
  raise "server is already running" if !stopped?
  @shutdown = false
  @maxConnections = maxConnections if maxConnections > 0
  @@servicesMutex.synchronize  {
    if GServer.in_service?(@port,@host)
      raise "Port already in use: #{host}:#{@port}!"
    end
    @tcpServer = TCPServer.new(@host,@port)
    @port = @tcpServer.addr[1]
    @@services[@host] = {} unless @@services.has_key?(@host)
    @@services[@host][@port] = self;
  }
  @tcpServerThread = Thread.new {
    begin
      starting if @audit
      while !@shutdown
        @connectionsMutex.synchronize  {
           while @connections.size >= @maxConnections
             @connectionsCV.wait(@connectionsMutex)
           end
        }
        client = @tcpServer.accept
        Thread.new(client)  { |myClient|
          @connections << Thread.current
          begin
            myPort = myClient.peeraddr[1]
            serve(myClient) if !@audit or connecting(myClient)
          rescue => detail
            error(detail) if @debug
          ensure
            begin
              myClient.close
            rescue
            end
            @connectionsMutex.synchronize {
              @connections.delete(Thread.current)
              @connectionsCV.signal
            }
            disconnecting(myPort) if @audit
          end
        }
      end
    rescue => detail
      error(detail) if @debug
    ensure
      begin
        @tcpServer.close
      rescue
      end
      if @shutdown
        @connectionsMutex.synchronize  {
           while @connections.size > 0
             @connectionsCV.wait(@connectionsMutex)
           end
        }
      else
        @connections.each { |c| c.raise "stop" }
      end
      @tcpServerThread = nil
      @@servicesMutex.synchronize  {
        @@services[@host].delete(@port)
      }
      stopping if @audit
    end
  }
  self
end
stop() click to toggle source

Stop the server

# File lib/gserver.rb, line 115
def stop
  @connectionsMutex.synchronize  {
    if @tcpServerThread
      @tcpServerThread.raise "stop"
    end
  }
end
stopped?() click to toggle source

Returns true if the server has stopped.

# File lib/gserver.rb, line 124
def stopped?
  @tcpServerThread == nil
end

Protected Instance Methods

connecting(client) click to toggle source

Called when a client connects, if auditing is enabled.

client

a TCPSocket instance representing the client that connected

Return true to allow this client to connect, false to prevent it.

# File lib/gserver.rb, line 162
def connecting(client)
  addr = client.peeraddr
  log("#{self.class.to_s} #{@host}:#{@port} client:#{addr[1]} " +
      "#{addr[2]}<#{addr[3]}> connect")
  true
end
disconnecting(clientPort) click to toggle source

Called when a client disconnects, if audition is enabled.

clientPort

the port of the client that is connecting

# File lib/gserver.rb, line 173
def disconnecting(clientPort)
  log("#{self.class.to_s} #{@host}:#{@port} " +
    "client:#{clientPort} disconnect")
end
error(detail) click to toggle source

Called if debug is true whenever an unhandled exception is raised. This implementation simply logs the backtrace.

detail

the Exception that was caught

# File lib/gserver.rb, line 196
def error(detail)
  log(detail.backtrace.join("\n"))
end
log(msg) click to toggle source

Log a message to stdlog, if it's defined. This implementation outputs the timestamp and message to the log.

msg

the message to log

# File lib/gserver.rb, line 204
def log(msg)
  if @stdlog
    @stdlog.puts("[#{Time.new.ctime}] %s" % msg)
    @stdlog.flush
  end
end
starting() click to toggle source

Called when the server is starting up, if auditing is enabled.

# File lib/gserver.rb, line 181
def starting()
  log("#{self.class.to_s} #{@host}:#{@port} start")
end
stopping() click to toggle source

Called when the server is shutting down, if auditing is enabled.

# File lib/gserver.rb, line 186
def stopping()
  log("#{self.class.to_s} #{@host}:#{@port} stop")
end


module Gem - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem

RubyGems is the Ruby standard for publishing and managing third party libraries.

For user documentation, see:

  • gem help and gem help [command]

  • RubyGems User Guide

  • Frequently Asked Questions

For gem developer documentation see:

  • Creating Gems

  • Gem::Specification

  • Gem::Version for version dependency notes

Further RubyGems documentation can be found at:

  • RubyGems Guides

  • RubyGems API (also available from gem server)

RubyGems Plugins

As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or $LOAD_PATH. Plugins must be named 'rubygems_plugin' (.rb, .so, etc) and placed at the root of your gem's require_path. Plugins are discovered via ::find_files then loaded. Take care when implementing a plugin as your plugin file may be loaded multiple times if multiple versions of your gem are installed.

For an example plugin, see the graph gem which adds a `gem graph` command.

RubyGems Defaults, Packaging

RubyGems defaults are stored in rubygems/defaults.rb. If you're packaging RubyGems or implementing Ruby you can change RubyGems' defaults.

For RubyGems packagers, provide lib/rubygems/operating_system.rb and override any defaults from lib/rubygems/defaults.rb.

For Ruby implementers, provide lib/rubygems/defaults/#{RUBY_ENGINE}.rb and override any defaults from lib/rubygems/defaults.rb.

If you need RubyGems to perform extra work on install or uninstall, your defaults override file can set pre and post install and uninstall hooks. See ::pre_install, ::pre_uninstall, ::post_install, ::post_uninstall.

Bugs

You can submit bugs to the RubyGems bug tracker on GitHub

Credits

RubyGems is currently maintained by Eric Hodel.

RubyGems was originally developed at RubyConf 2003 by:

  • Rich Kilmer – rich(at)infoether.com

  • Chad Fowler – chad(at)chadfowler.com

  • David Black – dblack(at)wobblini.net

  • Paul Brannan – paul(at)atdesk.com

  • Jim Weirch – jim(at)weirichhouse.org

Contributors:

  • Gavin Sinclair – gsinclair(at)soyabean.com.au

  • George Marrows – george.marrows(at)ntlworld.com

  • Dick Davies – rasputnik(at)hellooperator.net

  • Mauricio Fernandez – batsman.geo(at)yahoo.com

  • Simon Strandgaard – neoneye(at)adslhome.dk

  • Dave Glasser – glasser(at)mit.edu

  • Paul Duncan – pabs(at)pablotron.org

  • Ville Aine – vaine(at)cs.helsinki.fi

  • Eric Hodel – drbrain(at)segment7.net

  • Daniel Berger – djberg96(at)gmail.com

  • Phil Hagelberg – technomancy(at)gmail.com

  • Ryan Davis – ryand-ruby(at)zenspider.com

  • Evan Phoenix – evan(at)fallingsnow.net

  • Steve Klabnik – steve(at)steveklabnik.com

(If your name is missing, PLEASE let us know!)

See LICENSE.txt for permissions.

Thanks!

-The RubyGems Team

In Files

  • lib/rubygems/compatibility.rb
  • lib/rubygems/defaults.rb
  • lib/rubygems/dependency_resolver.rb
  • lib/rubygems/errors.rb
  • lib/rubygems/psych_tree.rb
  • lib/rubygems/rdoc.rb
  • lib/rubygems/request_set.rb
  • lib/rubygems/syck_hack.rb
  • lib/rubygems/test_case.rb
  • lib/rubygems.rb

Constants

DEFAULT_HOST
GEM_DEP_FILES
MARSHAL_SPEC_DIR

Location of Marshal quick gemspecs on remote repositories

RDoc
REPOSITORY_SUBDIRECTORIES

Subdirectories in a gem repository

RUBYGEMS_DIR
VERSION
WIN_PATTERNS

An Array of Regexps that match windows ruby platforms.

Attributes

done_installing_hooks[R]

The list of hooks to be run after Gem::DependencyInstaller installs a set of gems

loaded_specs[R]

Hash of loaded Gem::Specification keyed by name

post_build_hooks[R]

The list of hooks to be run after Gem::Installer#install extracts files and builds extensions

post_install_hooks[R]

The list of hooks to be run after Gem::Installer#install completes installation

post_reset_hooks[R]

The list of hooks to be run after Gem::Specification.reset is run.

post_uninstall_hooks[R]

The list of hooks to be run after Gem::Uninstaller#uninstall completes installation

pre_install_hooks[R]

The list of hooks to be run before Gem::Installer#install does any work

pre_reset_hooks[R]

The list of hooks to be run before Gem::Specification.reset is run.

pre_uninstall_hooks[R]

The list of hooks to be run before Gem::Uninstaller#uninstall does any work

Public Class Methods

bin_path(name, exec_name = nil, *requirements) click to toggle source

Find the full path to the executable for gem name. If the exec_name is not given, the gem's default_executable is chosen, otherwise the specified executable's path is returned. requirements allows you to specify specific gem versions.

# File lib/rubygems.rb, line 258
def self.bin_path(name, exec_name = nil, *requirements)
  # TODO: fails test_self_bin_path_bin_file_gone_in_latest
  # Gem::Specification.find_by_name(name, *requirements).bin_file exec_name

  raise ArgumentError, "you must supply exec_name" unless exec_name

  requirements = Gem::Requirement.default if
    requirements.empty?

  specs = Gem::Dependency.new(name, requirements).matching_specs(true)

  raise Gem::GemNotFoundException,
        "can't find gem #{name} (#{requirements})" if specs.empty?

  specs = specs.find_all { |spec|
    spec.executables.include? exec_name
  } if exec_name

  unless spec = specs.last
    msg = "can't find gem #{name} (#{requirements}) with executable #{exec_name}"
    raise Gem::GemNotFoundException, msg
  end

  spec.bin_file exec_name
end
binary_mode() click to toggle source

The mode needed to read a file as straight binary.

# File lib/rubygems.rb, line 287
def self.binary_mode
  'rb'
end
bindir(install_dir=Gem.dir) click to toggle source

The path where gem executables are to be installed.

# File lib/rubygems.rb, line 294
def self.bindir(install_dir=Gem.dir)
  # TODO: move to Gem::Dirs
  return File.join install_dir, 'bin' unless
    install_dir.to_s == Gem.default_dir.to_s
  Gem.default_bindir
end
clear_default_specs() click to toggle source

Clear default gem related varibles. It is for test

# File lib/rubygems.rb, line 1006
def clear_default_specs
  @path_to_default_spec_map.clear
end
clear_paths() click to toggle source

Reset the dir and path values. The next time dir or path is requested, the values will be calculated from scratch. This is mainly used by the unit tests to provide test isolation.

# File lib/rubygems.rb, line 306
def self.clear_paths
  @paths         = nil
  @user_home     = nil
  Gem::Specification.reset
  Gem::Security.reset if defined?(Gem::Security)
end
config_file() click to toggle source

The path to standard location of the user's .gemrc file.

# File lib/rubygems.rb, line 316
def self.config_file
  @config_file ||= File.join Gem.user_home, '.gemrc'
end
configuration() click to toggle source

The standard configuration object for gems.

# File lib/rubygems.rb, line 323
def self.configuration
  @configuration ||= Gem::ConfigFile.new []
end
configuration=(config) click to toggle source

Use the given configuration object (which implements the ConfigFile protocol) as the standard configuration object.

# File lib/rubygems.rb, line 331
def self.configuration=(config)
  @configuration = config
end
datadir(gem_name) click to toggle source

The path the the data directory specified by the gem name. If the package is not available as a gem, return nil.

# File lib/rubygems.rb, line 339
  def self.datadir(gem_name)
# TODO: deprecate and move to Gem::Specification
#       and drop the extra ", gem_name" which is uselessly redundant
    spec = @loaded_specs[gem_name]
    return nil if spec.nil?
    File.join spec.full_gem_path, "data", gem_name
  end
default_bindir() click to toggle source

The default directory for binaries

# File lib/rubygems/defaults.rb, line 97
def self.default_bindir
  if defined? RUBY_FRAMEWORK_VERSION then # mac framework support
    '/usr/bin'
  else # generic install
    ConfigMap[:bindir]
  end
end
default_cert_path() click to toggle source

The default signing certificate chain path

# File lib/rubygems/defaults.rb, line 126
def self.default_cert_path
  File.join Gem.user_home, ".gem", "gem-public_cert.pem"
end
default_dir() click to toggle source

Default home directory path to be used if an alternate value is not specified in the environment

# File lib/rubygems/defaults.rb, line 21
def self.default_dir
  path = if defined? RUBY_FRAMEWORK_VERSION then
           [
             File.dirname(ConfigMap[:sitedir]),
             'Gems',
             ConfigMap[:ruby_version]
           ]
         elsif ConfigMap[:rubylibprefix] then
           [
            ConfigMap[:rubylibprefix],
            'gems',
            ConfigMap[:ruby_version]
           ]
         else
           [
             ConfigMap[:libdir],
             ruby_engine,
             'gems',
             ConfigMap[:ruby_version]
           ]
         end

  @default_dir ||= File.join(*path)
end
default_exec_format() click to toggle source

Deduce Ruby's –program-prefix and –program-suffix from its install name

# File lib/rubygems/defaults.rb, line 83
def self.default_exec_format
  exec_format = ConfigMap[:ruby_install_name].sub('ruby', '%s') rescue '%s'

  unless exec_format =~ /%s/ then
    raise Gem::Exception,
      "[BUG] invalid exec_format #{exec_format.inspect}, no %s"
  end

  exec_format
end
default_key_path() click to toggle source

The default signing key path

# File lib/rubygems/defaults.rb, line 119
def self.default_key_path
  File.join Gem.user_home, ".gem", "gem-private_key.pem"
end
default_path() click to toggle source

Default gem load path

# File lib/rubygems/defaults.rb, line 72
def self.default_path
  if Gem.user_home && File.exist?(Gem.user_home) then
    [user_dir, default_dir]
  else
    [default_dir]
  end
end
default_rubygems_dirs() click to toggle source

Paths where RubyGems' .rb files and bin files are installed

# File lib/rubygems/defaults.rb, line 49
def self.default_rubygems_dirs
  nil # default to standard layout
end
default_sources() click to toggle source

An Array of the default sources that come with RubyGems

# File lib/rubygems/defaults.rb, line 13
def self.default_sources
  %w[https://rubygems.org/]
end
deflate(data) click to toggle source

A Zlib::Deflate.deflate wrapper

# File lib/rubygems.rb, line 350
def self.deflate(data)
  require 'zlib'
  Zlib::Deflate.deflate data
end
detect_gemdeps() click to toggle source
# File lib/rubygems.rb, line 208
def self.detect_gemdeps
  if path = ENV['RUBYGEMS_GEMDEPS']
    path = path.dup.untaint

    if path == "-"
      here = Dir.pwd.untaint
      start = here

      begin
        while true
          path = GEM_DEP_FILES.find { |f| File.file?(f) }

          if path
            path = File.join here, path
            break
          end

          Dir.chdir ".."

          # If we're at a toplevel, stop.
          return if Dir.pwd == here

          here = Dir.pwd
        end
      ensure
        Dir.chdir start
      end
    end

    path.untaint

    return unless File.file? path

    rs = Gem::RequestSet.new
    rs.load_gemdeps path

    rs.resolve_current.map do |s|
      sp = s.full_spec
      sp.activate
      sp
    end
  end
end
dir() click to toggle source

The path where gems are to be installed.

# File lib/rubygems.rb, line 372
def self.dir
  # TODO: raise "no"
  paths.home
end
done_installing(&hook) click to toggle source

Adds a post-installs hook that will be passed a Gem::DependencyInstaller and a list of installed specifications when Gem::DependencyInstaller#install is complete

# File lib/rubygems.rb, line 676
def self.done_installing(&hook)
  @done_installing_hooks << hook
end
ensure_gem_subdirectories(dir = Gem.dir, mode = nil) click to toggle source

Quietly ensure the Gem directory dir contains all the proper subdirectories. If we can't create a directory due to a permission problem, then we will silently continue.

If mode is given, missing directories are created with this mode.

World-writable directories will never be created.

# File lib/rubygems.rb, line 391
def self.ensure_gem_subdirectories dir = Gem.dir, mode = nil
  old_umask = File.umask
  File.umask old_umask | 002

  require 'fileutils'

  options = {}

  options[:mode] = mode if mode

  REPOSITORY_SUBDIRECTORIES.each do |name|
    subdir = File.join dir, name
    next if File.exist? subdir
    FileUtils.mkdir_p subdir, options rescue nil
  end
ensure
  File.umask old_umask
end
find_files(glob, check_load_path=true) click to toggle source

Returns a list of paths matching glob that can be used by a gem to pick up features from other gems. For example:

Gem.find_files('rdoc/discover').each do |path| load path end

if check_load_path is true (the default), then ::find_files also searches $LOAD_PATH for files as well as gems.

Note that ::find_files will return all files even if they are from different versions of the same gem.

# File lib/rubygems.rb, line 422
def self.find_files(glob, check_load_path=true)
  files = []

  if check_load_path
    files = $LOAD_PATH.map { |load_path|
      Dir["#{File.expand_path glob, load_path}#{Gem.suffix_pattern}"]
    }.flatten.select { |file| File.file? file.untaint }
  end

  files.concat Gem::Specification.map { |spec|
    spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}")
  }.flatten

  # $LOAD_PATH might contain duplicate entries or reference
  # the spec dirs directly, so we prune.
  files.uniq! if check_load_path

  return files
end
find_unresolved_default_spec(path) click to toggle source

Find a Gem::Specification of default gem from path

# File lib/rubygems.rb, line 985
def find_unresolved_default_spec(path)
  Gem.suffixes.each do |suffix|
    spec = @path_to_default_spec_map["#{path}#{suffix}"]
    return spec if spec
  end
  nil
end
finish_resolve(request_set=Gem::RequestSet.new) click to toggle source
# File lib/rubygems.rb, line 200
def self.finish_resolve(request_set=Gem::RequestSet.new)
  request_set.import Gem::Specification.unresolved_deps.values

  request_set.resolve_current.each do |s|
    s.full_spec.activate
  end
end
gunzip(data) click to toggle source

Zlib::GzipReader wrapper that unzips data.

# File lib/rubygems.rb, line 485
def self.gunzip(data)
  # TODO: move to utils
  require 'stringio'
  require 'zlib'
  data = StringIO.new data

  unzipped = Zlib::GzipReader.new(data).read
  unzipped.force_encoding Encoding::BINARY if Object.const_defined? :Encoding
  unzipped
end
gzip(data) click to toggle source

Zlib::GzipWriter wrapper that zips data.

# File lib/rubygems.rb, line 499
def self.gzip(data)
  # TODO: move to utils
  require 'stringio'
  require 'zlib'
  zipped = StringIO.new
  zipped.set_encoding Encoding::BINARY if Object.const_defined? :Encoding

  Zlib::GzipWriter.wrap zipped do |io| io.write data end

  zipped.string
end
host() click to toggle source

Get the default RubyGems API host. This is normally https://rubygems.org.

# File lib/rubygems.rb, line 539
def self.host
  # TODO: move to utils
  @host ||= Gem::DEFAULT_HOST
end
host=(host) click to toggle source

Set the default RubyGems API host.

# File lib/rubygems.rb, line 546
def self.host= host
  # TODO: move to utils
  @host = host
end
inflate(data) click to toggle source

A Zlib::Inflate#inflate wrapper

# File lib/rubygems.rb, line 514
def self.inflate(data)
  # TODO: move to utils
  require 'zlib'
  Zlib::Inflate.inflate data
end
install(name, version = Gem::Requirement.default) click to toggle source

Top level install helper method. Allows you to install gems interactively:

%Qirb
>> Gem.install "minitest"
Fetching: minitest-3.0.1.gem (100%)
=> [#<Gem::Specification:0x1013b4528 @name="minitest", ...>]

# File lib/rubygems.rb, line 528
def self.install name, version = Gem::Requirement.default
  require "rubygems/dependency_installer"
  inst = Gem::DependencyInstaller.new
  inst.install name, version
  inst.installed_gems
end
latest_rubygems_version() click to toggle source

Returns the latest release version of RubyGems.

# File lib/rubygems.rb, line 782
def self.latest_rubygems_version
  latest_version_for('rubygems-update') or
    raise "Can't find 'rubygems-update' in any repo. Check `gem source list`."
end
latest_spec_for(name) click to toggle source

Returns the latest release-version specification for the gem name.

# File lib/rubygems.rb, line 769
def self.latest_spec_for name
  dependency   = Gem::Dependency.new name
  fetcher      = Gem::SpecFetcher.fetcher
  spec_tuples, = fetcher.spec_for_dependency dependency

  spec, = spec_tuples.first

  spec
end
latest_version_for(name) click to toggle source

Returns the version of the latest release-version of gem name

# File lib/rubygems.rb, line 790
def self.latest_version_for name
  spec = latest_spec_for name
  spec and spec.version
end
load_env_plugins() click to toggle source

Find all 'rubygems_plugin' files in $LOAD_PATH and load them

# File lib/rubygems.rb, line 948
def self.load_env_plugins
  path = "rubygems_plugin"

  files = []
  $LOAD_PATH.each do |load_path|
    globbed = Dir["#{File.expand_path path, load_path}#{Gem.suffix_pattern}"]

    globbed.each do |load_path_file|
      files << load_path_file if File.file?(load_path_file.untaint)
    end
  end

  load_plugin_files files
end
load_path_insert_index() click to toggle source

The index to insert activated gem paths into the $LOAD_PATH.

Defaults to the site lib directory unless gem_prelude.rb has loaded paths, then it inserts the activated gem's paths before the gem_prelude.rb paths so you can override the gem_prelude.rb default $LOAD_PATH paths.

# File lib/rubygems.rb, line 558
def self.load_path_insert_index
  index = $LOAD_PATH.index ConfigMap[:sitelibdir]

  index
end
load_plugin_files(plugins) click to toggle source

Load plugins as ruby files

# File lib/rubygems.rb, line 921
def self.load_plugin_files(plugins)
  plugins.each do |plugin|

    # Skip older versions of the GemCutter plugin: Its commands are in
    # RubyGems proper now.

    next if plugin =~ /gemcutter-0\.[0-3]/

    begin
      load plugin
    rescue ::Exception => e
      details = "#{plugin.inspect}: #{e.message} (#{e.class})"
      warn "Error loading RubyGems plugin #{details}"
    end
  end
end
load_plugins() click to toggle source

Find all 'rubygems_plugin' files in installed gems and load them

# File lib/rubygems.rb, line 941
def self.load_plugins
  load_plugin_files find_files('rubygems_plugin', false)
end
load_yaml() click to toggle source

Loads YAML, preferring Psych

# File lib/rubygems.rb, line 569
def self.load_yaml
  return if @yaml_loaded
  return unless defined?(gem)

  test_syck = ENV['TEST_SYCK']

  unless test_syck
    begin
      gem 'psych', '~> 1.2', '>= 1.2.1'
    rescue Gem::LoadError
      # It's OK if the user does not have the psych gem installed.  We will
      # attempt to require the stdlib version
    end

    begin
      # Try requiring the gem version *or* stdlib version of psych.
      require 'psych'
    rescue ::LoadError
      # If we can't load psych, thats fine, go on.
    else
      # If 'yaml' has already been required, then we have to
      # be sure to switch it over to the newly loaded psych.
      if defined?(YAML::ENGINE) && YAML::ENGINE.yamler != "psych"
        YAML::ENGINE.yamler = "psych"
      end

      require 'rubygems/psych_additions'
      require 'rubygems/psych_tree'
    end
  end

  require 'yaml'

  # If we're supposed to be using syck, then we may have to force
  # activate it via the YAML::ENGINE API.
  if test_syck and defined?(YAML::ENGINE)
    YAML::ENGINE.yamler = "syck" unless YAML::ENGINE.syck?
  end

  # Now that we're sure some kind of yaml library is loaded, pull
  # in our hack to deal with Syck's DefaultKey ugliness.
  require 'rubygems/syck_hack'

  @yaml_loaded = true
end
location_of_caller() click to toggle source

The file name and line number of the caller of the caller of this method.

# File lib/rubygems.rb, line 618
def self.location_of_caller
  caller[1] =~ /(.*?):(\d+).*?$/
  file = $1
  lineno = $2.to_i

  # TODO: it is ALWAYS joined! STUPID!
  [file, lineno]
end
marshal_version() click to toggle source

The version of the Marshal format for your Ruby.

# File lib/rubygems.rb, line 630
def self.marshal_version
  "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
end
needs() { |rs| ... } click to toggle source
# File lib/rubygems.rb, line 192
def self.needs
  rs = Gem::RequestSet.new

  yield rs

  finish_resolve rs
end
path() click to toggle source
# File lib/rubygems.rb, line 377
def self.path
  # TODO: raise "no"
  paths.path
end
path_separator() click to toggle source

How String Gem paths should be split. Overridable for esoteric platforms.

# File lib/rubygems/defaults.rb, line 65
def self.path_separator
  File::PATH_SEPARATOR
end
paths() click to toggle source

DOC: needs doc'd or :nodoc'd

# File lib/rubygems.rb, line 356
def self.paths
  @paths ||= Gem::PathSupport.new
end
paths=(env) click to toggle source

DOC: needs doc'd or :nodoc'd

# File lib/rubygems.rb, line 361
def self.paths=(env)
  clear_paths
  @paths = Gem::PathSupport.new env
  Gem::Specification.dirs = @paths.path # FIX: home is at end
end
platforms() click to toggle source

Array of platforms this RubyGems supports.

# File lib/rubygems.rb, line 644
def self.platforms
  @platforms ||= []
  if @platforms.empty?
    @platforms = [Gem::Platform::RUBY, Gem::Platform.local]
  end
  @platforms
end
platforms=(platforms) click to toggle source

Set array of platforms this RubyGems supports (primarily for testing).

# File lib/rubygems.rb, line 637
def self.platforms=(platforms)
  @platforms = platforms
end
post_build(&hook) click to toggle source

Adds a post-build hook that will be passed an Gem::Installer instance when Gem::Installer#install is called. The hook is called after the gem has been extracted and extensions have been built but before the executables or gemspec has been written. If the hook returns false then the gem's files will be removed and the install will be aborted.

# File lib/rubygems.rb, line 659
def self.post_build(&hook)
  @post_build_hooks << hook
end
post_install(&hook) click to toggle source

Adds a post-install hook that will be passed an Gem::Installer instance when Gem::Installer#install is called

# File lib/rubygems.rb, line 667
def self.post_install(&hook)
  @post_install_hooks << hook
end
post_reset(&hook) click to toggle source

Adds a hook that will get run after Gem::Specification.reset is run.

# File lib/rubygems.rb, line 684
def self.post_reset(&hook)
  @post_reset_hooks << hook
end
post_uninstall(&hook) click to toggle source

Adds a post-uninstall hook that will be passed a Gem::Uninstaller instance and the spec that was uninstalled when Gem::Uninstaller#uninstall is called

# File lib/rubygems.rb, line 693
def self.post_uninstall(&hook)
  @post_uninstall_hooks << hook
end
pre_install(&hook) click to toggle source

Adds a pre-install hook that will be passed an Gem::Installer instance when Gem::Installer#install is called. If the hook returns false then the install will be aborted.

# File lib/rubygems.rb, line 702
def self.pre_install(&hook)
  @pre_install_hooks << hook
end
pre_reset(&hook) click to toggle source

Adds a hook that will get run before Gem::Specification.reset is run.

# File lib/rubygems.rb, line 710
def self.pre_reset(&hook)
  @pre_reset_hooks << hook
end
pre_uninstall(&hook) click to toggle source

Adds a pre-uninstall hook that will be passed an Gem::Uninstaller instance and the spec that will be uninstalled when Gem::Uninstaller#uninstall is called

# File lib/rubygems.rb, line 719
def self.pre_uninstall(&hook)
  @pre_uninstall_hooks << hook
end
prefix() click to toggle source

The directory prefix this RubyGems was installed at. If your prefix is in a standard location (ie, rubygems is installed where you'd expect it to be), then prefix returns nil.

# File lib/rubygems.rb, line 728
def self.prefix
  prefix = File.dirname RUBYGEMS_DIR

  if prefix != File.expand_path(ConfigMap[:sitelibdir]) and
     prefix != File.expand_path(ConfigMap[:libdir]) and
     'lib' == File.basename(RUBYGEMS_DIR) then
    prefix
  end
end
read_binary(path) click to toggle source

Safely read a file in binary mode on all platforms.

# File lib/rubygems.rb, line 748
def self.read_binary(path)
  File.open path, binary_mode do |f| f.read end
end
refresh() click to toggle source

Refresh available gems from disk.

# File lib/rubygems.rb, line 741
def self.refresh
  Gem::Specification.reset
end
register_default_spec(spec) click to toggle source

Register a Gem::Specification for default gem

# File lib/rubygems.rb, line 976
def register_default_spec(spec)
  spec.files.each do |file|
    @path_to_default_spec_map[file] = spec
  end
end
remove_unresolved_default_spec(spec) click to toggle source

Remove needless Gem::Specification of default gem from unresolved default gem list

# File lib/rubygems.rb, line 997
def remove_unresolved_default_spec(spec)
  spec.files.each do |file|
    @path_to_default_spec_map.delete(file)
  end
end
ruby() click to toggle source

The path to the running Ruby interpreter.

# File lib/rubygems.rb, line 755
def self.ruby
  if @ruby.nil? then
    @ruby = File.join(ConfigMap[:bindir],
                      "#{ConfigMap[:ruby_install_name]}#{ConfigMap[:EXEEXT]}")

    @ruby = "\"#{@ruby}\"" if @ruby =~ /\s/
  end

  @ruby
end
ruby=(ruby) click to toggle source

Allows setting path to ruby. This method is available when requiring 'rubygems/test_case'

# File lib/rubygems/test_case.rb, line 64
def self.ruby= ruby
  @ruby = ruby
end
ruby_engine() click to toggle source

A wrapper around RUBY_ENGINE const that may not be defined

# File lib/rubygems/defaults.rb, line 108
def self.ruby_engine
  if defined? RUBY_ENGINE then
    RUBY_ENGINE
  else
    'ruby'
  end
end
ruby_version() click to toggle source

A Gem::Version for the currently running ruby.

# File lib/rubygems.rb, line 798
def self.ruby_version
  return @ruby_version if defined? @ruby_version
  version = RUBY_VERSION.dup

  if defined?(RUBY_PATCHLEVEL) && RUBY_PATCHLEVEL != -1 then
    version << ".#{RUBY_PATCHLEVEL}"
  elsif defined?(RUBY_REVISION) then
    version << ".dev.#{RUBY_REVISION}"
  end

  @ruby_version = Gem::Version.new version
end
rubygems_version() click to toggle source

A Gem::Version for the currently running RubyGems

# File lib/rubygems.rb, line 814
def self.rubygems_version
  return @rubygems_version if defined? @rubygems_version
  @rubygems_version = Gem::Version.new Gem::VERSION
end
searcher=(searcher) click to toggle source

Allows setting the gem path searcher. This method is available when requiring 'rubygems/test_case'

# File lib/rubygems/test_case.rb, line 48
def self.searcher=(searcher)
  @searcher = searcher
end
sources() click to toggle source

Returns an Array of sources to fetch remote gems from. Uses ::default_sources if the sources list is empty.

# File lib/rubygems.rb, line 823
def self.sources
  @sources ||= Gem::SourceList.from(default_sources)
end
sources=(new_sources) click to toggle source

Need to be able to set the sources without calling ::sources.replace since that would cause an infinite loop.

DOC: This comment is not documentation about the method itself, it's more of a code comment about the implementation.

# File lib/rubygems.rb, line 834
def self.sources= new_sources
  if !new_sources
    @sources = nil
  else
    @sources = Gem::SourceList.from(new_sources)
  end
end
suffix_pattern() click to toggle source

Glob pattern for require-able path suffixes.

# File lib/rubygems.rb, line 845
def self.suffix_pattern
  @suffix_pattern ||= "{#{suffixes.join(',')}}"
end
suffixes() click to toggle source

Suffixes for require-able paths.

# File lib/rubygems.rb, line 852
def self.suffixes
  @suffixes ||= ['',
                 '.rb',
                 *%w(DLEXT DLEXT2).map { |key|
                   val = RbConfig::CONFIG[key]
                   next unless val and not val.empty?
                   ".#{val}"
                 }
                ].compact.uniq
end
time(msg, width = 0, display = Gem.configuration.verbose) { || ... } click to toggle source

Prints the amount of time the supplied block takes to run using the debug UI output.

# File lib/rubygems.rb, line 867
def self.time(msg, width = 0, display = Gem.configuration.verbose)
  now = Time.now

  value = yield

  elapsed = Time.now - now

  ui.say "%2$*1$s: %3$3.3fs" % [-width, msg, elapsed] if display

  value
end
try_activate(path) click to toggle source

Try to activate a gem containing path. Returns true if activation succeeded or wasn't needed because it was already activated. Returns false if it can't find the path in a gem.

# File lib/rubygems.rb, line 168
def self.try_activate path
  # finds the _latest_ version... regardless of loaded specs and their deps
  # if another gem had a requirement that would mean we shouldn't
  # activate the latest version, then either it would alreaby be activated
  # or if it was ambigious (and thus unresolved) the code in our custom
  # require will try to activate the more specific version.

  spec = Gem::Specification.find_inactive_by_path path

  unless spec
    spec = Gem::Specification.find_by_path path
    return true if spec && spec.activated?
    return false
  end

  begin
    spec.activate
  rescue Gem::LoadError # this could fail due to gem dep collisions, go lax
    Gem::Specification.find_by_name(spec.name).activate
  end

  return true
end
ui() click to toggle source

Lazily loads DefaultUserInteraction and returns the default UI.

# File lib/rubygems.rb, line 882
def self.ui
  require 'rubygems/user_interaction'

  Gem::DefaultUserInteraction.ui
end
use_paths(home, *paths) click to toggle source

Use the home and paths values for ::dir and ::path. Used mainly by the unit tests to provide environment isolation.

# File lib/rubygems.rb, line 892
def self.use_paths(home, *paths)
  paths = nil if paths == [nil]
  paths = paths.first if Array === Array(paths).first
  self.paths = { "GEM_HOME" => home, "GEM_PATH" => paths }
  # TODO: self.paths = home, paths
end
user_dir() click to toggle source

Path for gems in the user's home directory

# File lib/rubygems/defaults.rb, line 56
def self.user_dir
  parts = [Gem.user_home, '.gem', ruby_engine]
  parts << ConfigMap[:ruby_version] unless ConfigMap[:ruby_version].empty?
  File.join parts
end
user_home() click to toggle source

The home directory for the user.

# File lib/rubygems.rb, line 902
def self.user_home
  @user_home ||= find_home.untaint
end
win_platform=(val) click to toggle source

Allows toggling Windows behavior. This method is available when requiring 'rubygems/test_case'

# File lib/rubygems/test_case.rb, line 56
def self.win_platform=(val)
  @@win_platform = val
end
win_platform?() click to toggle source

Is this a windows platform?

# File lib/rubygems.rb, line 909
def self.win_platform?
  if @@win_platform.nil? then
    ruby_platform = RbConfig::CONFIG['host_os']
    @@win_platform = !!WIN_PATTERNS.find { |r| ruby_platform =~ r }
  end

  @@win_platform
end


class Gem::AvailableSet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::AvailableSet

In Files

  • lib/rubygems/available_set.rb

Parent

Object

Constants

Tuple

Attributes

set[R]

Public Class Methods

new() click to toggle source
# File lib/rubygems/available_set.rb, line 4
def initialize
  @set = []
  @sorted = nil
end

Public Instance Methods

<<(o) click to toggle source
# File lib/rubygems/available_set.rb, line 17
def <<(o)
  case o
  when Gem::AvailableSet
    s = o.set
  when Array
    s = o.map do |sp,so|
      if !sp.kind_of?(Gem::Specification) or !so.kind_of?(Gem::Source)
        raise TypeError, "Array must be in [[spec, source], ...] form"
      end

      Tuple.new(sp,so)
    end
  else
    raise TypeError, "must be a Gem::AvailableSet"
  end

  @set += s
  @sorted = nil

  self
end
add(spec, source) click to toggle source
# File lib/rubygems/available_set.rb, line 11
def add(spec, source)
  @set << Tuple.new(spec, source)
  @sorted = nil
  self
end
all_specs() click to toggle source
# File lib/rubygems/available_set.rb, line 43
def all_specs
  @set.map { |t| t.spec }
end
empty?() click to toggle source
# File lib/rubygems/available_set.rb, line 39
def empty?
  @set.empty?
end
inject_into_list(dep_list) click to toggle source
# File lib/rubygems/available_set.rb, line 90
def inject_into_list(dep_list)
  @set.each { |t| dep_list.add t.spec }
end
match_platform!() click to toggle source
# File lib/rubygems/available_set.rb, line 47
def match_platform!
  @set.reject! { |t| !Gem::Platform.match(t.spec.platform) }
  @sorted = nil
  self
end
pick_best!() click to toggle source
# File lib/rubygems/available_set.rb, line 69
def pick_best!
  return self if empty?

  @set = [sorted.first]
  @sorted = nil
  self
end
remove_installed!(dep) click to toggle source
# File lib/rubygems/available_set.rb, line 77
def remove_installed!(dep)
  @set.reject! do |t|
    # already locally installed
    Gem::Specification.any? do |installed_spec|
      dep.name == installed_spec.name and
        dep.requirement.satisfied_by? installed_spec.version
    end
  end

  @sorted = nil
  self
end
size() click to toggle source
# File lib/rubygems/available_set.rb, line 60
def size
  @set.size
end
sorted() click to toggle source
# File lib/rubygems/available_set.rb, line 53
def sorted
  @sorted ||= @set.sort do |a,b|
    i = b.spec <=> a.spec
    i != 0 ? i : (a.source <=> b.source)
  end
end
source_for(spec) click to toggle source
# File lib/rubygems/available_set.rb, line 64
def source_for(spec)
  f = @set.find { |t| t.spec == spec }
  f.source
end


class Gem::Command - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Command

Base class for all Gem commands. When creating a new gem command, define initialize, execute, arguments, defaults_str, description and usage (as appropriate). See the above mentioned methods for details.

A very good example to look at is Gem::Commands::ContentsCommand

In Files

  • lib/rubygems/command.rb

Parent

Object

Included Modules

  • Gem::UserInteraction

Attributes

command[R]

The name of the command.

defaults[RW]

The default options for the command.

options[R]

The options for the command.

program_name[RW]

The name of the command for command-line invocation.

summary[RW]

A short description of the command.

Public Class Methods

add_common_option(*args, &handler) click to toggle source
# File lib/rubygems/command.rb, line 62
def self.add_common_option(*args, &handler)
  Gem::Command.common_options << [args, handler]
end
add_specific_extra_args(cmd,args) click to toggle source

Add a list of extra arguments for the given command. args may be an array or a string to be split on white space.

# File lib/rubygems/command.rb, line 91
def self.add_specific_extra_args(cmd,args)
  args = args.split(/\s+/) if args.kind_of? String
  specific_extra_args_hash[cmd] = args
end
build_args() click to toggle source

Arguments used when building gems

# File lib/rubygems/command.rb, line 50
def self.build_args
  @build_args ||= []
end
build_args=(value) click to toggle source
# File lib/rubygems/command.rb, line 54
def self.build_args=(value)
  @build_args = value
end
common_options() click to toggle source
# File lib/rubygems/command.rb, line 58
def self.common_options
  @common_options ||= []
end
extra_args() click to toggle source
# File lib/rubygems/command.rb, line 66
def self.extra_args
  @extra_args ||= []
end
extra_args=(value) click to toggle source
# File lib/rubygems/command.rb, line 70
def self.extra_args=(value)
  case value
  when Array
    @extra_args = value
  when String
    @extra_args = value.split
  end
end
new(command, summary=nil, defaults={}) click to toggle source

Initializes a generic gem command named command. summary is a short description displayed in `gem help commands`. defaults are the default options. Defaults should be mirrored in defaults_str, unless there are none.

When defining a new command subclass, use #add_option to add command-line switches.

Unhandled arguments (gem names, files, etc.) are left in options[:args].

# File lib/rubygems/command.rb, line 117
def initialize(command, summary=nil, defaults={})
  @command = command
  @summary = summary
  @program_name = "gem #{command}"
  @defaults = defaults
  @options = defaults.dup
  @option_groups = Hash.new { |h,k| h[k] = [] }
  @parser = nil
  @when_invoked = nil
end
specific_extra_args(cmd) click to toggle source

Return an array of extra arguments for the command. The extra arguments come from the gem configuration file read at program startup.

# File lib/rubygems/command.rb, line 83
def self.specific_extra_args(cmd)
  specific_extra_args_hash[cmd]
end
specific_extra_args_hash() click to toggle source

Accessor for the specific extra args hash (self initializing).

# File lib/rubygems/command.rb, line 99
def self.specific_extra_args_hash
  @specific_extra_args_hash ||= Hash.new do |h,k|
    h[k] = Array.new
  end
end

Public Instance Methods

add_extra_args(args) click to toggle source

Adds extra args from ~/.gemrc

# File lib/rubygems/command.rb, line 382
def add_extra_args(args)
  result = []

  s_extra = Gem::Command.specific_extra_args(@command)
  extra = Gem::Command.extra_args + s_extra

  until extra.empty? do
    ex = []
    ex << extra.shift
    ex << extra.shift if extra.first.to_s =~ /^[^-]/
    result << ex if handles?(ex)
  end

  result.flatten!
  result.concat(args)
  result
end
add_option(*opts) { |value, options| ... } click to toggle source

Add a command-line option and handler to the command.

See OptionParser#make_switch for an explanation of opts.

handler will be called with two values, the value of the argument and the options hash.

If the first argument of #add_option is a Symbol, it's used to group options in output. See `gem help list` for an example.

# File lib/rubygems/command.rb, line 332
def add_option(*opts, &handler) # :yields: value, options
  group_name = Symbol === opts.first ? opts.shift : :options

  @option_groups[group_name] << [opts, handler]
end
arguments() click to toggle source

Override to provide details of the arguments a command takes. It should return a left-justified string, one argument per line.

For example:

def usage
  "#{program_name} FILE [FILE ...]"
end

def arguments
  "FILE          name of file to find"
end

# File lib/rubygems/command.rb, line 242
def arguments
  ""
end
begins?(long, short) click to toggle source

True if long begins with the characters from short.

# File lib/rubygems/command.rb, line 131
def begins?(long, short)
  return false if short.nil?
  long[0, short.length] == short
end
defaults_str() click to toggle source

Override to display the default values of the command options. (similar to arguments, but displays the default values).

For example:

def defaults_str
  --no-gems-first --no-all
end

# File lib/rubygems/command.rb, line 256
def defaults_str
  ""
end
description() click to toggle source

Override to display a longer description of what this command does.

# File lib/rubygems/command.rb, line 263
def description
  nil
end
execute() click to toggle source

Override to provide command handling.

options will be filled in with your parsed options, unparsed options will be left in options[:args].

See also: get_all_gem_names, get_one_gem_name, get_one_optional_argument

# File lib/rubygems/command.rb, line 145
def execute
  raise Gem::Exception, "generic command has no actions"
end
get_all_gem_names() click to toggle source

Get all gem names from the command line.

# File lib/rubygems/command.rb, line 173
def get_all_gem_names
  args = options[:args]

  if args.nil? or args.empty? then
    raise Gem::CommandLineError,
          "Please specify at least one gem name (e.g. gem build GEMNAME)"
  end

  args.select { |arg| arg !~ /^-/ }
end
get_all_gem_names_and_versions() click to toggle source

Get all [gem, version] from the command line.

An argument in the form gem:ver is pull apart into the gen name and version, respectively.

# File lib/rubygems/command.rb, line 189
def get_all_gem_names_and_versions
  get_all_gem_names.map do |name|
    if /\A(.*):(#{Gem::Requirement::PATTERN_RAW})\z/ =~ name
      [$1, $2]
    else
      [name]
    end
  end
end
get_one_gem_name() click to toggle source

Get a single gem name from the command line. Fail if there is no gem name or if there is more than one gem name given.

# File lib/rubygems/command.rb, line 203
def get_one_gem_name
  args = options[:args]

  if args.nil? or args.empty? then
    raise Gem::CommandLineError,
          "Please specify a gem name on the command line (e.g. gem build GEMNAME)"
  end

  if args.size > 1 then
    raise Gem::CommandLineError,
          "Too many gem names (#{args.join(', ')}); please specify only one"
  end

  args.first
end
get_one_optional_argument() click to toggle source

Get a single optional argument from the command line. If more than one argument is given, return only the first. Return nil if none are given.

# File lib/rubygems/command.rb, line 223
def get_one_optional_argument
  args = options[:args] || []
  args.first
end
handle_options(args) click to toggle source

Handle the given list of arguments by parsing them and recording the results.

# File lib/rubygems/command.rb, line 372
def handle_options(args)
  args = add_extra_args(args)
  @options = Marshal.load Marshal.dump @defaults # deep copy
  parser.parse!(args)
  @options[:args] = args
end
handles?(args) click to toggle source

True if the command handles the given argument list.

# File lib/rubygems/command.rb, line 359
def handles?(args)
  begin
    parser.parse!(args.dup)
    return true
  rescue
    return false
  end
end
invoke(*args) click to toggle source

Invoke the command with the given list of arguments.

# File lib/rubygems/command.rb, line 287
def invoke(*args)
  invoke_with_build_args args, nil
end
invoke_with_build_args(args, build_args) click to toggle source

Invoke the command with the given list of normal arguments and additional build arguments.

# File lib/rubygems/command.rb, line 295
def invoke_with_build_args(args, build_args)
  handle_options args

  options[:build_args] = build_args

  if options[:help] then
    show_help
  elsif @when_invoked then
    @when_invoked.call options
  else
    execute
  end
end
merge_options(new_options) click to toggle source

Merge a set of command options with the set of default options (without modifying the default option hash).

# File lib/rubygems/command.rb, line 351
def merge_options(new_options)
  @options = @defaults.clone
  new_options.each do |k,v| @options[k] = v end
end
remove_option(name) click to toggle source

Remove previously defined command-line argument name.

# File lib/rubygems/command.rb, line 341
def remove_option(name)
  @option_groups.each do |_, option_list|
    option_list.reject! { |args, _| args.any? { |x| x =~ /^#{name}/ } }
  end
end
show_help() click to toggle source

Display the help message for the command.

# File lib/rubygems/command.rb, line 279
def show_help
  parser.program_name = usage
  say parser
end
show_lookup_failure(gem_name, version, errors, domain) click to toggle source

Display to the user that a gem couldn't be found and reasons why

# File lib/rubygems/command.rb, line 152
def show_lookup_failure(gem_name, version, errors, domain)
  if errors and !errors.empty?
    msg = "Could not find a valid gem '#{gem_name}' (#{version}), here is why:\n"
    errors.each { |x| msg << "          #{x.wordy}\n" }
    alert_error msg
  else
    alert_error "Could not find a valid gem '#{gem_name}' (#{version}) in any repository"
  end

  unless domain == :local then # HACK
    suggestions = Gem::SpecFetcher.fetcher.suggest_gems_from_name gem_name

    unless suggestions.empty?
      alert_error "Possible alternatives: #{suggestions.join(", ")}"
    end
  end
end
usage() click to toggle source

Override to display the usage for an individual gem command.

The text “[options]” is automatically appended to the usage text.

# File lib/rubygems/command.rb, line 272
def usage
  program_name
end
when_invoked(&block) click to toggle source

Call the given block when invoked.

Normal command invocations just executes the execute method of the command. Specifying an invocation block allows the test methods to override the normal action of a command to determine that it has been invoked correctly.

# File lib/rubygems/command.rb, line 317
def when_invoked(&block)
  @when_invoked = block
end

Private Instance Methods

wrap(text, width) click to toggle source

Wraps text to width

# File lib/rubygems/command.rb, line 498
def wrap(text, width) # :doc:
  text.gsub(/(.{1,#{width}})( +|$\n?)|(.{1,#{width}})/, "\\1\\3\n")
end


class Gem::CommandLineError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::CommandLineError

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::CommandManager - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::CommandManager

The command manager registers and installs all the individual sub-commands supported by the gem command.

Extra commands can be provided by writing a rubygems_plugin.rb file in an installed gem. You should register your command against the Gem::CommandManager instance, like this:

# file rubygems_plugin.rb
require 'rubygems/command_manager'

Gem::CommandManager.instance.register_command :edit

You should put the implementation of your command in rubygems/commands.

# file rubygems/commands/edit_command.rb
class Gem::Commands::EditCommand < Gem::Command
  # ...
end

See Gem::Command for instructions on writing gem commands.

In Files

  • lib/rubygems/command_manager.rb

Parent

Object

Included Modules

  • Gem::UserInteraction

Public Class Methods

instance() click to toggle source

Return the authoritative instance of the command manager.

# File lib/rubygems/command_manager.rb, line 39
def self.instance
  @command_manager ||= new
end
new() click to toggle source

Register all the subcommands supported by the gem command.

# File lib/rubygems/command_manager.rb, line 61
def initialize
  require 'timeout'
  @commands = {}
  register_command :build
  register_command :cert
  register_command :check
  register_command :cleanup
  register_command :contents
  register_command :dependency
  register_command :environment
  register_command :fetch
  register_command :generate_index
  register_command :help
  register_command :install
  register_command :list
  register_command :lock
  register_command :mirror
  register_command :outdated
  register_command :owner
  register_command :pristine
  register_command :push
  register_command :query
  register_command :rdoc
  register_command :search
  register_command :server
  register_command :sources
  register_command :specification
  register_command :stale
  register_command :uninstall
  register_command :unpack
  register_command :update
  register_command :which
  register_command :yank
end
reset() click to toggle source

Reset the authoritative instance of the command manager.

# File lib/rubygems/command_manager.rb, line 54
def self.reset
  @command_manager = nil
end

Public Instance Methods

[](command_name) click to toggle source

Returns a Command instance for command_name

# File lib/rubygems/command_manager.rb, line 113
def [](command_name)
  command_name = command_name.intern
  return nil if @commands[command_name].nil?
  @commands[command_name] ||= load_and_instantiate(command_name)
end
command_names() click to toggle source

Return a sorted list of all command names as strings.

# File lib/rubygems/command_manager.rb, line 122
def command_names
  @commands.keys.collect {|key| key.to_s}.sort
end
find_command(cmd_name) click to toggle source
# File lib/rubygems/command_manager.rb, line 174
def find_command(cmd_name)
  possibilities = find_command_possibilities cmd_name

  if possibilities.size > 1 then
    raise Gem::CommandLineError,
          "Ambiguous command #{cmd_name} matches [#{possibilities.join(', ')}]"
  elsif possibilities.empty? then
    raise Gem::CommandLineError, "Unknown command #{cmd_name}"
  end

  self[possibilities.first]
end
find_command_possibilities(cmd_name) click to toggle source
# File lib/rubygems/command_manager.rb, line 187
def find_command_possibilities(cmd_name)
  len = cmd_name.length

  found = command_names.select { |name| cmd_name == name[0, len] }

  exact = found.find { |name| name == cmd_name }

  exact ? [exact] : found
end
instance() click to toggle source

Returns self. Allows a CommandManager instance to stand in for the class itself.

# File lib/rubygems/command_manager.rb, line 47
def instance
  self
end
process_args(args, build_args=nil) click to toggle source
# File lib/rubygems/command_manager.rb, line 149
def process_args(args, build_args=nil)
  args = args.to_str.split(/\s+/) if args.respond_to?(:to_str)

  if args.empty? then
    say Gem::Command::HELP
    terminate_interaction 1
  end

  case args.first
  when '-h', '--help' then
    say Gem::Command::HELP
    terminate_interaction 0
  when '-v', '--version' then
    say Gem::VERSION
    terminate_interaction 0
  when /^-/ then
    alert_error "Invalid option: #{args.first}.  See 'gem --help'."
    terminate_interaction 1
  else
    cmd_name = args.shift.downcase
    cmd = find_command cmd_name
    cmd.invoke_with_build_args args, build_args
  end
end
register_command(command, obj=false) click to toggle source

Register the Symbol command as a gem command.

# File lib/rubygems/command_manager.rb, line 99
def register_command(command, obj=false)
  @commands[command] = obj
end
run(args, build_args=nil) click to toggle source

Run the command specified by args.

# File lib/rubygems/command_manager.rb, line 129
def run(args, build_args=nil)
  process_args(args, build_args)
rescue StandardError, Timeout::Error => ex
  alert_error "While executing gem ... (#{ex.class})\n    #{ex.to_s}"
  ui.backtrace ex

  if Gem.configuration.really_verbose and           ex.kind_of?(Gem::Exception) and ex.source_exception
    e = ex.source_exception

    ui.errs.puts "Because of: (#{e.class})\n    #{e.to_s}"
    ui.backtrace e
  end

  terminate_interaction(1)
rescue Interrupt
  alert_error "Interrupted"
  terminate_interaction(1)
end
unregister_command(command) click to toggle source

Unregister the Symbol command as a gem command.

# File lib/rubygems/command_manager.rb, line 106
def unregister_command(command)
  @commands.delete command
end


module Gem::Commands - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::Commands

Commands will be placed in this namespace

In Files

  • lib/rubygems/command.rb


class Gem::Commands::BuildCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::BuildCommand

In Files

  • lib/rubygems/commands/build_command.rb

Parent

Gem::Command

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/build_command.rb, line 6
def initialize
  super 'build', 'Build a gem from a gemspec'

  add_option '--force', 'skip validation of the spec' do |value, options|
    options[:force] = true
  end
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/build_command.rb, line 22
def execute
  gemspec = get_one_gem_name

  if File.exist? gemspec then
    spec = Gem::Specification.load gemspec

    if spec then
      Gem::Package.build spec, options[:force]
    else
      alert_error "Error loading gemspec. Aborting."
      terminate_interaction 1
    end
  else
    alert_error "Gemspec file not found: #{gemspec}"
    terminate_interaction 1
  end
end


class Gem::Commands::CertCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::CertCommand

In Files

  • lib/rubygems/commands/cert_command.rb

Parent

Gem::Command

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/cert_command.rb, line 7
def initialize
  super 'cert', 'Manage RubyGems certificates and signing settings',
        :add => [], :remove => [], :list => [], :build => [], :sign => []

  OptionParser.accept OpenSSL::X509::Certificate do |certificate|
    begin
      OpenSSL::X509::Certificate.new File.read certificate
    rescue Errno::ENOENT
      raise OptionParser::InvalidArgument, "#{certificate}: does not exist"
    rescue OpenSSL::X509::CertificateError
      raise OptionParser::InvalidArgument,
        "#{certificate}: invalid X509 certificate"
    end
  end

  OptionParser.accept OpenSSL::PKey::RSA do |key_file|
    begin
      key = OpenSSL::PKey::RSA.new File.read key_file
    rescue Errno::ENOENT
      raise OptionParser::InvalidArgument, "#{key_file}: does not exist"
    rescue OpenSSL::PKey::RSAError
      raise OptionParser::InvalidArgument, "#{key_file}: invalid RSA key"
    end

    raise OptionParser::InvalidArgument,
          "#{key_file}: private key not found" unless key.private?

    key
  end

  add_option('-a', '--add CERT', OpenSSL::X509::Certificate,
             'Add a trusted certificate.') do |cert, options|
    options[:add] << cert
  end

  add_option('-l', '--list [FILTER]',
             'List trusted certificates where the',
             'subject contains FILTER') do |filter, options|
    filter ||= ''

    options[:list] << filter
  end

  add_option('-r', '--remove FILTER',
             'Remove trusted certificates where the',
             'subject contains FILTER') do |filter, options|
    options[:remove] << filter
  end

  add_option('-b', '--build EMAIL_ADDR',
             'Build private key and self-signed',
             'certificate for EMAIL_ADDR') do |email_address, options|
    options[:build] << email_address
  end

  add_option('-C', '--certificate CERT', OpenSSL::X509::Certificate,
             'Signing certificate for --sign') do |cert, options|
    options[:issuer_cert] = cert
  end

  add_option('-K', '--private-key KEY', OpenSSL::PKey::RSA,
             'Key for --sign or --build') do |key, options|
    options[:key] = key
  end

  add_option('-s', '--sign CERT',
             'Signs CERT with the key from -K',
             'and the certificate from -C') do |cert_file, options|
    raise OptionParser::InvalidArgument, "#{cert_file}: does not exist" unless
      File.file? cert_file

    options[:sign] << cert_file
  end
end

Public Instance Methods

build(name) click to toggle source
# File lib/rubygems/commands/cert_command.rb, line 117
def build name
  key = options[:key] || Gem::Security.create_key

  cert = Gem::Security.create_cert_email name, key

  key_path  = Gem::Security.write key, "gem-private_key.pem"
  cert_path = Gem::Security.write cert, "gem-public_cert.pem"

  say "Certificate: #{cert_path}"
  say "Private Key: #{key_path}"
  say "Don't forget to move the key file to somewhere private!"
end
certificates_matching(filter) { |certificate, path| ... } click to toggle source
# File lib/rubygems/commands/cert_command.rb, line 130
def certificates_matching filter
  return enum_for __method__, filter unless block_given?

  Gem::Security.trusted_certificates.select do |certificate, _|
    subject = certificate.subject.to_s
    subject.downcase.index filter
  end.sort_by do |certificate, _|
    certificate.subject.to_a.map { |name, data,| [name, data] }
  end.each do |certificate, path|
    yield certificate, path
  end
end
execute() click to toggle source
# File lib/rubygems/commands/cert_command.rb, line 82
def execute
  options[:add].each do |certificate|
    Gem::Security.trust_dir.trust_cert certificate

    say "Added '#{certificate.subject}'"
  end

  options[:remove].each do |filter|
    certificates_matching filter do |certificate, path|
      FileUtils.rm path
      say "Removed '#{certificate.subject}'"
    end
  end

  options[:list].each do |filter|
    certificates_matching filter do |certificate, _|
      # this could probably be formatted more gracefully
      say certificate.subject.to_s
    end
  end

  options[:build].each do |name|
    build name
  end

  unless options[:sign].empty? then
    load_default_cert unless options[:issuer_cert]
    load_default_key  unless options[:key]
  end

  options[:sign].each do |cert_file|
    sign cert_file
  end
end
load_default_cert() click to toggle source
# File lib/rubygems/commands/cert_command.rb, line 182
def load_default_cert
  cert_file = File.join Gem.default_cert_path
  cert = File.read cert_file
  options[:issuer_cert] = OpenSSL::X509::Certificate.new cert
rescue Errno::ENOENT
  alert_error        "--certificate not specified and ~/.gem/gem-public_cert.pem does not exist"

  terminate_interaction 1
rescue OpenSSL::X509::CertificateError
  alert_error        "--certificate not specified and ~/.gem/gem-public_cert.pem is not valid"

  terminate_interaction 1
end
load_default_key() click to toggle source
# File lib/rubygems/commands/cert_command.rb, line 198
def load_default_key
  key_file = File.join Gem.default_key_path
  key = File.read key_file
  options[:key] = OpenSSL::PKey::RSA.new key
rescue Errno::ENOENT
  alert_error        "--private-key not specified and ~/.gem/gem-private_key.pem does not exist"

  terminate_interaction 1
rescue OpenSSL::PKey::RSAError
  alert_error        "--private-key not specified and ~/.gem/gem-private_key.pem is not valid"

  terminate_interaction 1
end
sign(cert_file) click to toggle source
# File lib/rubygems/commands/cert_command.rb, line 214
def sign cert_file
  cert = File.read cert_file
  cert = OpenSSL::X509::Certificate.new cert

  permissions = File.stat(cert_file).mode & 0777

  issuer_cert = options[:issuer_cert]
  issuer_key = options[:key]

  cert = Gem::Security.sign cert, issuer_key, issuer_cert

  Gem::Security.write cert, cert_file, permissions
end


class Gem::Commands::CheckCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::CheckCommand

In Files

  • lib/rubygems/commands/check_command.rb

Parent

Gem::Command

Included Modules

  • Gem::VersionOption

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/check_command.rb, line 10
def initialize
  super 'check', 'Check a gem repository for added or missing files',
        :alien => true, :doctor => false, :dry_run => false, :gems => true

  add_option('-a', '--[no-]alien',
             'Report "unmanaged" or rogue files in the',
             'gem repository') do |value, options|
    options[:alien] = value
  end

  add_option('--[no-]doctor',
             'Clean up uninstalled gems and broken',
             'specifications') do |value, options|
    options[:doctor] = value
  end

  add_option('--[no-]dry-run',
             'Do not remove files, only report what',
             'would be removed') do |value, options|
    options[:dry_run] = value
  end

  add_option('--[no-]gems',
             'Check installed gems for problems') do |value, options|
    options[:gems] = value
  end

  add_version_option 'check'
end

Public Instance Methods

check_gems() click to toggle source
# File lib/rubygems/commands/check_command.rb, line 40
def check_gems
  say 'Checking gems...'
  say
  gems = get_all_gem_names rescue []

  Gem::Validator.new.alien(gems).sort.each do |key, val|
    unless val.empty? then
      say "#{key} has #{val.size} problems"
      val.each do |error_entry|
        say "  #{error_entry.path}:"
        say "    #{error_entry.problem}"
      end
    else
      say "#{key} is error-free" if Gem.configuration.verbose
    end
    say
  end
end
doctor() click to toggle source
# File lib/rubygems/commands/check_command.rb, line 59
def doctor
  say 'Checking for files from uninstalled gems...'
  say

  Gem.path.each do |gem_repo|
    doctor = Gem::Doctor.new gem_repo, options[:dry_run]
    doctor.doctor
  end
end
execute() click to toggle source
# File lib/rubygems/commands/check_command.rb, line 69
def execute
  check_gems if options[:gems]
  doctor if options[:doctor]
end


class Gem::Commands::CleanupCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::CleanupCommand

In Files

  • lib/rubygems/commands/cleanup_command.rb

Parent

Gem::Command

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/cleanup_command.rb, line 7
def initialize
  super 'cleanup',
        'Clean up old versions of installed gems in the local repository',
        :force => false, :install_dir => Gem.dir

  add_option('-d', '--dryrun', "") do |value, options|
    options[:dryrun] = true
  end

  @candidate_gems  = nil
  @default_gems    = []
  @full            = nil
  @gems_to_cleanup = nil
  @original_home   = nil
  @original_path   = nil
  @primary_gems    = nil
end

Public Instance Methods

clean_gems() click to toggle source
# File lib/rubygems/commands/cleanup_command.rb, line 76
def clean_gems
  get_primary_gems
  get_candidate_gems
  get_gems_to_cleanup

  @full = Gem::DependencyList.from_specs

  deplist = Gem::DependencyList.new
  @gems_to_cleanup.each do |spec| deplist.add spec end

  deps = deplist.strongly_connected_components.flatten

  @original_home = Gem.dir
  @original_path = Gem.path

  deps.reverse_each do |spec|
    uninstall_dep spec
  end

  Gem::Specification.reset
end
execute() click to toggle source
# File lib/rubygems/commands/cleanup_command.rb, line 47
def execute
  say "Cleaning up installed gems..."

  if options[:args].empty? then
    done     = false
    last_set = nil

    until done do
      clean_gems

      this_set = @gems_to_cleanup.map { |spec| spec.full_name }.sort

      done = this_set.empty? || last_set == this_set

      last_set = this_set
    end
  else
    clean_gems
  end

  say "Clean Up Complete"

  if Gem.configuration.really_verbose then
    skipped = @default_gems.map { |spec| spec.full_name }

    say "Skipped default gems: #{skipped.join ', '}"
  end
end
get_candidate_gems() click to toggle source
# File lib/rubygems/commands/cleanup_command.rb, line 98
def get_candidate_gems
  @candidate_gems = unless options[:args].empty? then
                      options[:args].map do |gem_name|
                        Gem::Specification.find_all_by_name gem_name
                      end.flatten
                    else
                      Gem::Specification.to_a
                    end
end
get_gems_to_cleanup() click to toggle source
# File lib/rubygems/commands/cleanup_command.rb, line 108
def get_gems_to_cleanup
  gems_to_cleanup = @candidate_gems.select { |spec|
    @primary_gems[spec.name].version != spec.version
  }

  default_gems, gems_to_cleanup = gems_to_cleanup.partition { |spec|
    spec.default_gem?
  }

  @default_gems += default_gems
  @default_gems.uniq!
  @gems_to_cleanup = gems_to_cleanup.uniq
end
get_primary_gems() click to toggle source
# File lib/rubygems/commands/cleanup_command.rb, line 122
def get_primary_gems
  @primary_gems = {}

  Gem::Specification.each do |spec|
    if @primary_gems[spec.name].nil? or
       @primary_gems[spec.name].version < spec.version then
      @primary_gems[spec.name] = spec
    end
  end
end
uninstall_dep(spec) click to toggle source
# File lib/rubygems/commands/cleanup_command.rb, line 133
def uninstall_dep spec
  return unless @full.ok_to_remove?(spec.full_name)

  if options[:dryrun] then
    say "Dry Run Mode: Would uninstall #{spec.full_name}"
    return
  end

  say "Attempting to uninstall #{spec.full_name}"

  uninstall_options = {
    :executables => false,
    :version => "= #{spec.version}",
  }

  uninstall_options[:user_install] = Gem.user_dir == spec.base_dir

  uninstaller = Gem::Uninstaller.new spec.name, uninstall_options

  begin
    uninstaller.uninstall
  rescue Gem::DependencyRemovalException, Gem::InstallError,
         Gem::GemNotInHomeException, Gem::FilePermissionError => e
    say "Unable to uninstall #{spec.full_name}:"
    say "\t#{e.class}: #{e.message}"
  end
ensure
  # Restore path Gem::Uninstaller may have changed
  Gem.use_paths @original_home, *@original_path
end


class Gem::Commands::ContentsCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::ContentsCommand

In Files

  • lib/rubygems/commands/contents_command.rb

Parent

Gem::Command

Included Modules

  • Gem::VersionOption

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/contents_command.rb, line 9
def initialize
  super 'contents', 'Display the contents of the installed gems',
        :specdirs => [], :lib_only => false, :prefix => true

  add_version_option

  add_option(      '--all',
             "Contents for all gems") do |all, options|
    options[:all] = all
  end

  add_option('-s', '--spec-dir a,b,c', Array,
             "Search for gems under specific paths") do |spec_dirs, options|
    options[:specdirs] = spec_dirs
  end

  add_option('-l', '--[no-]lib-only',
             "Only return files in the Gem's lib_dirs") do |lib_only, options|
    options[:lib_only] = lib_only
  end

  add_option(      '--[no-]prefix',
             "Don't include installed path prefix") do |prefix, options|
    options[:prefix] = prefix
  end
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/contents_command.rb, line 48
def execute
  version = options[:version] || Gem::Requirement.default

  spec_dirs = options[:specdirs].map do |i|
    [i, File.join(i, "specifications")]
  end.flatten

  path_kind = if spec_dirs.empty? then
                spec_dirs = Gem::Specification.dirs
                "default gem paths"
              else
                "specified path"
              end

  gem_names = if options[:all] then
                Gem::Specification.map(&:name)
              else
                get_all_gem_names
              end

  gem_names.each do |name|
    # HACK: find_by_name fails for some reason... ARGH
    # How many places must we embed our resolve logic?
    spec = Gem::Specification.find_all_by_name(name, version).last

    unless spec then
      say "Unable to find gem '#{name}' in #{path_kind}"

      if Gem.configuration.verbose then
        say "\nDirectories searched:"
        spec_dirs.sort.each { |dir| say dir }
      end

      terminate_interaction 1 if gem_names.length == 1
    end

    if spec.default_gem?
      files = spec.files.sort.map do |file|
        case file
        when /\A#{spec.bindir}\//
          [Gem::ConfigMap[:bindir], $POSTMATCH]
        when /\.so\z/
          [Gem::ConfigMap[:archdir], file]
        else
          [Gem::ConfigMap[:rubylibdir], file]
        end
      end
    else
      gem_path  = spec.full_gem_path
      extra     = "/{#{spec.require_paths.join ','}}" if options[:lib_only]
      glob      = "#{gem_path}#{extra}/**/*"
      prefix_re = /#{Regexp.escape(gem_path)}\//
      files     = Dir[glob].map do |file|
        [gem_path, file.sub(prefix_re, "")]
      end
    end

    files.sort.each do |prefix, basename|
      absolute_path = File.join(prefix, basename)
      next if File.directory? absolute_path

      if options[:prefix]
        say absolute_path
      else
        say basename
      end
    end
  end
end


class Gem::Commands::DependencyCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::DependencyCommand

In Files

  • lib/rubygems/commands/dependency_command.rb

Parent

Gem::Command

Included Modules

  • Gem::LocalRemoteOptions
  • Gem::VersionOption

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/dependency_command.rb, line 10
def initialize
  super 'dependency',
        'Show the dependencies of an installed gem',
        :version => Gem::Requirement.default, :domain => :local

  add_version_option
  add_platform_option
  add_prerelease_option

  add_option('-R', '--[no-]reverse-dependencies',
             'Include reverse dependencies in the output') do
    |value, options|
    options[:reverse_dependencies] = value
  end

  add_option('-p', '--pipe',
             "Pipe Format (name --version ver)") do |value, options|
    options[:pipe_format] = value
  end

  add_local_remote_options
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/dependency_command.rb, line 45
def execute
  if options[:reverse_dependencies] and remote? and not local? then
    alert_error 'Only reverse dependencies for local gems are supported.'
    terminate_interaction 1
  end

  options[:args] << '' if options[:args].empty?

  pattern = if options[:args].length == 1 and
               options[:args].first =~ /\A\/(.*)\/(i)?\z/ then
              flags = $2 ? Regexp::IGNORECASE : nil
              Regexp.new $1, flags
            else
              /\A#{Regexp.union(*options[:args])}/
            end

  # TODO: deprecate for real damnit
  dependency = Gem::Deprecate.skip_during {
    Gem::Dependency.new pattern, options[:version]
  }
  dependency.prerelease = options[:prerelease]

  specs = []

  specs.concat dependency.matching_specs if local?

  if remote? and not options[:reverse_dependencies] then
    fetcher = Gem::SpecFetcher.fetcher

    ss, _ = fetcher.spec_for_dependency dependency

    ss.each { |s,o| specs << s }
  end

  if specs.empty? then
    patterns = options[:args].join ','
    say "No gems found matching #{patterns} (#{options[:version]})" if
      Gem.configuration.verbose

    terminate_interaction 1
  end

  specs = specs.uniq.sort

  reverse = Hash.new { |h, k| h[k] = [] }

  if options[:reverse_dependencies] then
    specs.each do |spec|
      reverse[spec.full_name] = find_reverse_dependencies spec
    end
  end

  if options[:pipe_format] then
    specs.each do |spec|
      unless spec.dependencies.empty?
        spec.dependencies.sort_by { |dep| dep.name }.each do |dep|
          say "#{dep.name} --version '#{dep.requirement}'"
        end
      end
    end
  else
    response = ''

    specs.each do |spec|
      response << print_dependencies(spec)
      unless reverse[spec.full_name].empty? then
        response << "  Used by\n"
        reverse[spec.full_name].each do |sp, dep|
          response << "    #{sp} (#{dep})\n"
        end
      end
      response << "\n"
    end

    say response
  end
end
find_reverse_dependencies(spec) click to toggle source

Returns an Array of [specification, dep] that are satisfied by spec.

# File lib/rubygems/commands/dependency_command.rb, line 137
def find_reverse_dependencies(spec)
  result = []

  Gem::Specification.each do |sp|
    sp.dependencies.each do |dep|
      dep = Gem::Dependency.new(*dep) unless Gem::Dependency === dep

      if spec.name == dep.name and
         dep.requirement.satisfied_by?(spec.version) then
        result << [sp.full_name, dep]
      end
    end
  end

  result
end
print_dependencies(spec, level = 0) click to toggle source
# File lib/rubygems/commands/dependency_command.rb, line 123
def print_dependencies(spec, level = 0)
  response = ''
  response << '  ' * level + "Gem #{spec.full_name}\n"
  unless spec.dependencies.empty? then
    spec.dependencies.sort_by { |dep| dep.name }.each do |dep|
      response << '  ' * level + "  #{dep}\n"
    end
  end
  response
end


class Gem::Commands::EnvironmentCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::EnvironmentCommand

In Files

  • lib/rubygems/commands/environment_command.rb

Parent

Gem::Command

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/environment_command.rb, line 5
def initialize
  super 'environment', 'Display information about the RubyGems environment'
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/environment_command.rb, line 69
def execute
  out = ''
  arg = options[:args][0]
  case arg
  when /^packageversion/ then
    out << Gem::RubyGemsPackageVersion
  when /^version/ then
    out << Gem::VERSION
  when /^gemdir/, /^gemhome/, /^home/, /^GEM_HOME/ then
    out << Gem.dir
  when /^gempath/, /^path/, /^GEM_PATH/ then
    out << Gem.path.join(File::PATH_SEPARATOR)
  when /^remotesources/ then
    out << Gem.sources.to_a.join("\n")
  when /^platform/ then
    out << Gem.platforms.join(File::PATH_SEPARATOR)
  when nil then
    out = "RubyGems Environment:\n"

    out << "  - RUBYGEMS VERSION: #{Gem::VERSION}\n"

    out << "  - RUBY VERSION: #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}"
    out << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
    out << ") [#{RUBY_PLATFORM}]\n"

    out << "  - INSTALLATION DIRECTORY: #{Gem.dir}\n"

    out << "  - RUBYGEMS PREFIX: #{Gem.prefix}\n" unless Gem.prefix.nil?

    out << "  - RUBY EXECUTABLE: #{Gem.ruby}\n"

    out << "  - EXECUTABLE DIRECTORY: #{Gem.bindir}\n"

    out << "  - RUBYGEMS PLATFORMS:\n"
    Gem.platforms.each do |platform|
      out << "    - #{platform}\n"
    end

    out << "  - GEM PATHS:\n"
    out << "     - #{Gem.dir}\n"

    path = Gem.path.dup
    path.delete Gem.dir
    path.each do |p|
      out << "     - #{p}\n"
    end

    out << "  - GEM CONFIGURATION:\n"
    Gem.configuration.each do |name, value|
      value = value.gsub(/./, '*') if name == 'gemcutter_key'
      out << "     - #{name.inspect} => #{value.inspect}\n"
    end

    out << "  - REMOTE SOURCES:\n"
    Gem.sources.each do |s|
      out << "     - #{s}\n"
    end

  else
    raise Gem::CommandLineError, "Unknown environment option [#{arg}]"
  end
  say out
  true
end


class Gem::Commands::FetchCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::FetchCommand

In Files

  • lib/rubygems/commands/fetch_command.rb

Parent

Gem::Command

Included Modules

  • Gem::LocalRemoteOptions
  • Gem::VersionOption

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/fetch_command.rb, line 10
def initialize
  super 'fetch', 'Download a gem and place it in the current directory'

  add_bulk_threshold_option
  add_proxy_option
  add_source_option
  add_clear_sources_option

  add_version_option
  add_platform_option
  add_prerelease_option
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/fetch_command.rb, line 35
def execute
  version = options[:version] || Gem::Requirement.default

  platform  = Gem.platforms.last
  gem_names = get_all_gem_names

  gem_names.each do |gem_name|
    dep = Gem::Dependency.new gem_name, version
    dep.prerelease = options[:prerelease]

    specs_and_sources, errors = Gem::SpecFetcher.fetcher.spec_for_dependency dep

    if platform then
      filtered = specs_and_sources.select { |s,| s.platform == platform }
      specs_and_sources = filtered unless filtered.empty?
    end

    spec, source = specs_and_sources.max_by { |s,| s.version }

    if spec.nil? then
      show_lookup_failure gem_name, version, errors, options[:domain]
      next
    end

    source.download spec

    say "Downloaded #{spec.full_name}"
  end
end


class Gem::Commands::GenerateIndexCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::GenerateIndexCommand

Generates a index files for use as a gem server.

See `gem help generate_index`

In Files

  • lib/rubygems/commands/generate_index_command.rb

Parent

Gem::Command

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/generate_index_command.rb, line 11
def initialize
  super 'generate_index',
        'Generates the index files for a gem server directory',
        :directory => '.', :build_modern => true

  add_option '-d', '--directory=DIRNAME',
             'repository base dir containing gems subdir' do |dir, options|
    options[:directory] = File.expand_path dir
  end

  add_option '--[no-]modern',
             'Generate indexes for RubyGems',
             '(always true)' do |value, options|
    options[:build_modern] = value
  end

  add_option '--update',
             'Update modern indexes with gems added',
             'since the last update' do |value, options|
    options[:update] = value
  end
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/generate_index_command.rb, line 64
def execute
  # This is always true becasue it's the only way now.
  options[:build_modern] = true

  if not File.exist?(options[:directory]) or
     not File.directory?(options[:directory]) then
    alert_error "unknown directory name #{directory}."
    terminate_interaction 1
  else
    indexer = Gem::Indexer.new options.delete(:directory), options

    if options[:update] then
      indexer.update_index
    else
      indexer.generate_index
    end
  end
end


class Gem::Commands::HelpCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::HelpCommand

In Files

  • lib/rubygems/commands/help_command.rb

Parent

Gem::Command

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/help_command.rb, line 81
def initialize
  super 'help', "Provide help on the 'gem' command"
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/help_command.rb, line 98
def execute
  command_manager = Gem::CommandManager.instance
  arg = options[:args][0]

  if begins? "commands", arg then
    out = []
    out << "GEM commands are:"
    out << nil

    margin_width = 4

    desc_width = command_manager.command_names.map { |n| n.size }.max + 4

    summary_width = 80 - margin_width - desc_width
    wrap_indent = ' ' * (margin_width + desc_width)
    format = "#{' ' * margin_width}%-#{desc_width}s%s"

    command_manager.command_names.each do |cmd_name|
      command = command_manager[cmd_name]

      summary =
        if command then
          command.summary
        else
          "[No command found for #{cmd_name}, bug?]"
        end

      summary = wrap(summary, summary_width).split "\n"
      out << sprintf(format, cmd_name, summary.shift)
      until summary.empty? do
        out << "#{wrap_indent}#{summary.shift}"
      end
    end

    out << nil
    out << "For help on a particular command, use 'gem help COMMAND'."
    out << nil
    out << "Commands may be abbreviated, so long as they are unambiguous."
    out << "e.g. 'gem i rake' is short for 'gem install rake'."

    say out.join("\n")

  elsif begins? "options", arg then
    say Gem::Command::HELP

  elsif begins? "examples", arg then
    say EXAMPLES

  elsif begins? "platforms", arg then
    say PLATFORMS

  elsif options[:help] then
    command = command_manager[options[:help]]
    if command
      # help with provided command
      command.invoke("--help")
    else
      alert_error "Unknown command #{options[:help]}.  Try 'gem help commands'"
    end

  elsif arg then
    possibilities = command_manager.find_command_possibilities(arg.downcase)
    if possibilities.size == 1
      command = command_manager[possibilities.first]
      command.invoke("--help")
    elsif possibilities.size > 1
      alert_warning "Ambiguous command #{arg} (#{possibilities.join(', ')})"
    else
      alert_warning "Unknown command #{arg}. Try gem help commands"
    end

  else
    say Gem::Command::HELP
  end
end


class Gem::Commands::InstallCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::InstallCommand

Gem installer command line tool

See `gem help install`

In Files

  • lib/rubygems/commands/install_command.rb

Parent

Gem::Command

Included Modules

  • Gem::VersionOption
  • Gem::LocalRemoteOptions
  • Gem::InstallUpdateOptions

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/install_command.rb, line 23
def initialize
  defaults = Gem::DependencyInstaller::DEFAULT_OPTIONS.merge({
    :format_executable => false,
    :version           => Gem::Requirement.default,
  })

  super 'install', 'Install a gem into the local repository', defaults

  add_install_update_options
  add_local_remote_options
  add_platform_option
  add_version_option
  add_prerelease_option "to be installed. (Only for listed gems)"

  add_option(:"Install/Update", '-g', '--file FILE',
             'Read from a gem dependencies API file and',
             'install the listed gems') do |v,o|
    o[:gemdeps] = v
  end

  @installed_specs = nil
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/install_command.rb, line 134
def execute
  if gf = options[:gemdeps] then
    install_from_gemdeps gf
    return
  end

  @installed_specs = []

  ENV.delete 'GEM_PATH' if options[:install_dir].nil? and RUBY_VERSION > '1.9'

  if options[:install_dir] and options[:user_install]
    alert_error "Use --install-dir or --user-install but not both"
    terminate_interaction 1
  end

  exit_code = 0

  if options[:version] != Gem::Requirement.default &&
      get_all_gem_names.size > 1 then
    alert_error "Can't use --version w/ multiple gems. Use name:ver instead."
    terminate_interaction 1
  end

  get_all_gem_names_and_versions.each do |gem_name, gem_version|
    gem_version ||= options[:version]

    begin
      next if options[:conservative] and
        not Gem::Dependency.new(gem_name, gem_version).matching_specs.empty?

      inst = Gem::DependencyInstaller.new options
      inst.install gem_name, Gem::Requirement.create(gem_version)

      @installed_specs.push(*inst.installed_gems)

      next unless errs = inst.errors

      errs.each do |x|
        next unless Gem::SourceFetchProblem === x

        msg = "Unable to pull data from '#{x.source.uri}': #{x.error.message}"

        alert_warning msg
      end
    rescue Gem::InstallError => e
      alert_error "Error installing #{gem_name}:\n\t#{e.message}"
      exit_code |= 1
    rescue Gem::GemNotFoundException => e
      show_lookup_failure e.name, e.version, e.errors, options[:domain]

      exit_code |= 2
    end
  end

  unless @installed_specs.empty? then
    gems = @installed_specs.length == 1 ? 'gem' : 'gems'
    say "#{@installed_specs.length} #{gems} installed"
  end

  raise Gem::SystemExitException, exit_code
end
install_from_gemdeps(gf) click to toggle source
# File lib/rubygems/commands/install_command.rb, line 112
def install_from_gemdeps(gf)
  require 'rubygems/request_set'
  rs = Gem::RequestSet.new
  rs.load_gemdeps gf

  rs.resolve

  specs = rs.install options do |req, inst|
    s = req.full_spec

    if inst
      say "Installing #{s.name} (#{s.version})"
    else
      say "Using #{s.name} (#{s.version})"
    end
  end

  @installed_specs = specs

  raise Gem::SystemExitException, 0
end


class Gem::Commands::ListCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::ListCommand

An alternate to Gem::Commands::QueryCommand that searches for gems starting with the the supplied argument.

In Files

  • lib/rubygems/commands/list_command.rb

Parent

Gem::Commands::QueryCommand

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/list_command.rb, line 10
def initialize
  super 'list', 'Display gems whose name starts with STRING'

  remove_option('--name-matches')
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/list_command.rb, line 28
def execute
  string = get_one_optional_argument || ''
  options[:name] = /^#{string}/
  super
end


class Gem::Commands::LockCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::LockCommand

In Files

  • lib/rubygems/commands/lock_command.rb

Parent

Gem::Command

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/lock_command.rb, line 5
def initialize
  super 'lock', 'Generate a lockdown list of gems',
        :strict => false

  add_option '-s', '--[no-]strict',
             'fail if unable to satisfy a dependency' do |strict, options|
    options[:strict] = strict
  end
end

Public Instance Methods

complain(message) click to toggle source
# File lib/rubygems/commands/lock_command.rb, line 60
def complain(message)
  if options[:strict] then
    raise Gem::Exception, message
  else
    say "# #{message}"
  end
end
execute() click to toggle source
# File lib/rubygems/commands/lock_command.rb, line 68
def execute
  say "require 'rubygems'"

  locked = {}

  pending = options[:args]

  until pending.empty? do
    full_name = pending.shift

    spec = Gem::Specification.load spec_path(full_name)

    if spec.nil? then
      complain "Could not find gem #{full_name}, try using the full name"
      next
    end

    say "gem '#{spec.name}', '= #{spec.version}'" unless locked[spec.name]
    locked[spec.name] = true

    spec.runtime_dependencies.each do |dep|
      next if locked[dep.name]
      candidates = dep.matching_specs

      if candidates.empty? then
        complain "Unable to satisfy '#{dep}' from currently installed gems"
      else
        pending << candidates.last.full_name
      end
    end
  end
end
spec_path(gem_full_name) click to toggle source
# File lib/rubygems/commands/lock_command.rb, line 101
def spec_path(gem_full_name)
  gemspecs = Gem.path.map { |path|
    File.join path, "specifications", "#{gem_full_name}.gemspec"
  }

  gemspecs.find { |path| File.exist? path }
end


class Gem::Commands::MirrorCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::MirrorCommand

In Files

  • lib/rubygems/commands/mirror_command.rb

Parent

Gem::Command

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/mirror_command.rb, line 4
def initialize
  super('mirror', 'Mirror all gem files (requires rubygems-mirror)')
  begin
    Gem::Specification.find_by_name('rubygems-mirror').activate
  rescue Gem::LoadError
    # no-op
  end
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/mirror_command.rb, line 13
def execute
  alert_error "Install the rubygems-mirror gem for the mirror command"
end


class Gem::Commands::OutdatedCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::OutdatedCommand

In Files

  • lib/rubygems/commands/outdated_command.rb

Parent

Gem::Command

Included Modules

  • Gem::LocalRemoteOptions
  • Gem::VersionOption

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/outdated_command.rb, line 11
def initialize
  super 'outdated', 'Display all gems that need updates'

  add_local_remote_options
  add_platform_option
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/outdated_command.rb, line 18
def execute
  Gem::Specification.outdated.sort.each do |name|
    local   = Gem::Specification.find_all_by_name(name).max
    dep     = Gem::Dependency.new local.name, ">= #{local.version}"
    remotes, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dep

    next if remotes.empty?

    remotes.sort! { |a,b| a[0].version <=> b[0].version }

    highest = remotes.last.first

    say "#{local.name} (#{local.version} < #{highest.version})"
  end
end


class Gem::Commands::OwnerCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::OwnerCommand

In Files

  • lib/rubygems/commands/owner_command.rb

Parent

Gem::Command

Included Modules

  • Gem::LocalRemoteOptions
  • Gem::GemcutterUtilities

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/owner_command.rb, line 21
def initialize
  super 'owner', description
  add_proxy_option
  add_key_option
  defaults.merge! :add => [], :remove => []

  add_option '-a', '--add EMAIL', 'Add an owner' do |value, options|
    options[:add] << value
  end

  add_option '-r', '--remove EMAIL', 'Remove an owner' do |value, options|
    options[:remove] << value
  end
end

Public Instance Methods

add_owners(name, owners) click to toggle source
# File lib/rubygems/commands/owner_command.rb, line 60
def add_owners name, owners
  manage_owners :post, name, owners
end
execute() click to toggle source
# File lib/rubygems/commands/owner_command.rb, line 36
def execute
  sign_in
  name = get_one_gem_name

  add_owners    name, options[:add]
  remove_owners name, options[:remove]
  show_owners   name
end
manage_owners(method, name, owners) click to toggle source
# File lib/rubygems/commands/owner_command.rb, line 68
def manage_owners method, name, owners
  owners.each do |owner|
    begin
      response = rubygems_api_request method, "api/v1/gems/#{name}/owners" do |request|
        request.set_form_data 'email' => owner
        request.add_field "Authorization", api_key
      end

      with_response response, "Removing #{owner}"
    rescue
      # ignore
    end
  end
end
remove_owners(name, owners) click to toggle source
# File lib/rubygems/commands/owner_command.rb, line 64
def remove_owners name, owners
  manage_owners :delete, name, owners
end
show_owners(name) click to toggle source
# File lib/rubygems/commands/owner_command.rb, line 45
def show_owners name
  response = rubygems_api_request :get, "api/v1/gems/#{name}/owners.yaml" do |request|
    request.add_field "Authorization", api_key
  end

  with_response response do |resp|
    owners = YAML.load resp.body

    say "Owners for gem: #{name}"
    owners.each do |owner|
      say "- #{owner['email']}"
    end
  end
end


class Gem::Commands::PristineCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::PristineCommand

In Files

  • lib/rubygems/commands/pristine_command.rb

Parent

Gem::Command

Included Modules

  • Gem::VersionOption

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/pristine_command.rb, line 10
def initialize
  super 'pristine',
        'Restores installed gems to pristine condition from files located in the gem cache',
        :version => Gem::Requirement.default,
        :extensions => true,
        :all => false

  add_option('--all',
             'Restore all installed gems to pristine',
             'condition') do |value, options|
    options[:all] = value
  end

  add_option('--[no-]extensions',
             'Restore gems with extensions',
             'in addition to regular gems') do |value, options|
    options[:extensions] = value
  end

  add_option('--only-executables',
             'Only restore executables') do |value, options|
    options[:only_executables] = value
  end

  add_version_option('restore to', 'pristine condition')
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/pristine_command.rb, line 66
def execute
  specs = if options[:all] then
            Gem::Specification.map
          else
            get_all_gem_names.map do |gem_name|
              Gem::Specification.find_all_by_name gem_name, options[:version]
            end.flatten
          end

  if specs.to_a.empty? then
    raise Gem::Exception,
          "Failed to find gems #{options[:args]} #{options[:version]}"
  end

  install_dir = Gem.dir # TODO use installer option

  raise Gem::FilePermissionError.new(install_dir) unless
    File.writable?(install_dir)

  say "Restoring gems to pristine condition..."

  specs.each do |spec|
    if spec.default_gem?
      say "Skipped #{spec.full_name}, it is a default gem"
      next
    end

    unless spec.extensions.empty? or options[:extensions] then
      say "Skipped #{spec.full_name}, it needs to compile an extension"
      next
    end

    gem = spec.cache_file

    unless File.exist? gem then
      require 'rubygems/remote_fetcher'

      say "Cached gem for #{spec.full_name} not found, attempting to fetch..."
      dep = Gem::Dependency.new spec.name, spec.version
      Gem::RemoteFetcher.fetcher.download_to_cache dep
    end

    # TODO use installer options
    install_defaults = Gem::ConfigFile::PLATFORM_DEFAULTS['install']
    installer_env_shebang = install_defaults.to_s['--env-shebang']

    installer = Gem::Installer.new(gem,
                                   :wrappers => true,
                                   :force => true,
                                   :install_dir => spec.base_dir,
                                   :env_shebang => installer_env_shebang,
                                   :build_args => spec.build_args)
    if options[:only_executables] then
      installer.generate_bin
    else
      installer.install
    end

    say "Restored #{spec.full_name}"
  end
end


class Gem::Commands::PushCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::PushCommand

In Files

  • lib/rubygems/commands/push_command.rb

Parent

Gem::Command

Included Modules

  • Gem::LocalRemoteOptions
  • Gem::GemcutterUtilities

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/push_command.rb, line 22
def initialize
  super 'push', description, :host => self.host

  add_proxy_option
  add_key_option

  add_option('--host HOST',
             'Push to another gemcutter-compatible host') do |value, options|
    options[:host] = value
  end

  @host = nil
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/push_command.rb, line 36
def execute
  @host = options[:host]

  sign_in @host

  send_gem get_one_gem_name
end
send_gem(name) click to toggle source
# File lib/rubygems/commands/push_command.rb, line 44
  def send_gem name
    args = [:post, "api/v1/gems"]

    latest_rubygems_version = Gem.latest_rubygems_version

    if latest_rubygems_version < Gem.rubygems_version and
         Gem.rubygems_version.prerelease? and
         Gem::Version.new('2.0.0.rc.2') != Gem.rubygems_version then
      alert_error <<-ERROR
You are using a beta release of RubyGems (#{Gem::VERSION}) which is not
allowed to push gems.  Please downgrade or upgrade to a release version.

The latest released RubyGems version is #{latest_rubygems_version}

You can upgrade or downgrade to the latest release version with:

  gem update --system=#{latest_rubygems_version}

      ERROR
      terminate_interaction 1
    end

    unless @host then
      if gem_data = Gem::Package.new(name) then
        @host = gem_data.spec.metadata['default_gem_server']
      end
    end

    args << @host if @host

    say "Pushing gem to #{@host || Gem.host}..."

    response = rubygems_api_request(*args) do |request|
      request.body = Gem.read_binary name
      request.add_field "Content-Length", request.body.size
      request.add_field "Content-Type",   "application/octet-stream"
      request.add_field "Authorization",  api_key
    end

    with_response response
  end


class Gem::Commands::QueryCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::QueryCommand

In Files

  • lib/rubygems/commands/query_command.rb

Parent

Gem::Command

Included Modules

  • Gem::Text
  • Gem::LocalRemoteOptions
  • Gem::VersionOption

Public Class Methods

new(name = 'query', summary = 'Query gem information in local or remote repositories') click to toggle source
# File lib/rubygems/commands/query_command.rb, line 13
def initialize(name = 'query',
               summary = 'Query gem information in local or remote repositories')
  super name, summary,
       :name => //, :domain => :local, :details => false, :versions => true,
       :installed => nil, :version => Gem::Requirement.default

  add_option('-i', '--[no-]installed',
             'Check for installed gem') do |value, options|
    options[:installed] = value
  end

  add_option('-I', 'Equivalent to --no-installed') do |value, options|
    options[:installed] = false
  end

  add_version_option command, "for use with --installed"

  add_option('-n', '--name-matches REGEXP',
             'Name of gem(s) to query on matches the',
             'provided REGEXP') do |value, options|
    options[:name] = /#{value}/
  end

  add_option('-d', '--[no-]details',
             'Display detailed information of gem(s)') do |value, options|
    options[:details] = value
  end

  add_option(      '--[no-]versions',
             'Display only gem names') do |value, options|
    options[:versions] = value
    options[:details] = false unless value
  end

  add_option('-a', '--all',
             'Display all gem versions') do |value, options|
    options[:all] = value
  end

  add_option(      '--[no-]prerelease',
             'Display prerelease versions') do |value, options|
    options[:prerelease] = value
  end

  add_local_remote_options
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/query_command.rb, line 64
def execute
  exit_code = 0

  name = options[:name]
  prerelease = options[:prerelease]

  unless options[:installed].nil? then
    if name.source.empty? then
      alert_error "You must specify a gem name"
      exit_code |= 4
    else
      installed = installed? name, options[:version]
      installed = !installed unless options[:installed]

      if installed then
        say "true"
      else
        say "false"
        exit_code |= 1
      end
    end

    terminate_interaction exit_code
  end

  req = Gem::Requirement.default
  # TODO: deprecate for real
  dep = Gem::Deprecate.skip_during { Gem::Dependency.new name, req }
  dep.prerelease = prerelease

  if local? then
    if prerelease and not both? then
      alert_warning "prereleases are always shown locally"
    end

    if ui.outs.tty? or both? then
      say
      say "*** LOCAL GEMS ***"
      say
    end

    specs = Gem::Specification.find_all { |s|
      s.name =~ name and req =~ s.version
    }

    spec_tuples = specs.map do |spec|
      [spec.name_tuple, spec]
    end

    output_query_results spec_tuples
  end

  if remote? then
    if ui.outs.tty? or both? then
      say
      say "*** REMOTE GEMS ***"
      say
    end

    fetcher = Gem::SpecFetcher.fetcher

    type = if options[:all]
             if options[:prerelease]
               :complete
             else
               :released
             end
           elsif options[:prerelease]
             :prerelease
           else
             :latest
           end

    if options[:name].source.empty?
      spec_tuples = fetcher.detect(type) { true }
    else
      spec_tuples = fetcher.detect(type) do |name_tuple|
        options[:name] === name_tuple.name
      end
    end

    output_query_results spec_tuples
  end
end


class Gem::Commands::RdocCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::RdocCommand

In Files

  • lib/rubygems/commands/rdoc_command.rb

Parent

Gem::Command

Included Modules

  • Gem::VersionOption

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/rdoc_command.rb, line 9
def initialize
  super 'rdoc', 'Generates RDoc for pre-installed gems',
        :version => Gem::Requirement.default,
        :include_rdoc => false, :include_ri => true, :overwrite => false

  add_option('--all',
             'Generate RDoc/RI documentation for all',
             'installed gems') do |value, options|
    options[:all] = value
  end

  add_option('--[no-]rdoc',
             'Generate RDoc HTML') do |value, options|
    options[:include_rdoc] = value
  end

  add_option('--[no-]ri',
             'Generate RI data') do |value, options|
    options[:include_ri] = value
  end

  add_option('--[no-]overwrite',
             'Overwrite installed documents') do |value, options|
    options[:overwrite] = value
  end

  add_version_option
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/rdoc_command.rb, line 57
def execute
  specs = if options[:all] then
            Gem::Specification.to_a
          else
            get_all_gem_names.map do |name|
              Gem::Specification.find_by_name name, options[:version]
            end.flatten.uniq
          end

  if specs.empty? then
    alert_error 'No matching gems found'
    terminate_interaction 1
  end

  specs.each do |spec|
    doc = Gem::RDoc.new spec, options[:include_rdoc], options[:include_ri]

    doc.force = options[:overwrite]

    if options[:overwrite] then
      FileUtils.rm_rf File.join(spec.doc_dir, 'ri')
      FileUtils.rm_rf File.join(spec.doc_dir, 'rdoc')
    end

    begin
      doc.generate
    rescue Errno::ENOENT => e
      e.message =~ / - /
      alert_error "Unable to document #{spec.full_name}, #{$'} is missing, skipping"
      terminate_interaction 1 if specs.length == 1
    end
  end
end


class Gem::Commands::SearchCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::SearchCommand

In Files

  • lib/rubygems/commands/search_command.rb

Parent

Gem::Commands::QueryCommand

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/search_command.rb, line 6
def initialize
  super 'search', 'Display all gems whose name contains STRING'

  remove_option '--name-matches'

  defaults[:domain] = :remote
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/search_command.rb, line 26
def execute
  string = get_one_optional_argument
  options[:name] = /#{string}/
  super
end


class Gem::Commands::ServerCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::ServerCommand

In Files

  • lib/rubygems/commands/server_command.rb

Parent

Gem::Command

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/server_command.rb, line 6
def initialize
  super 'server', 'Documentation and gem repository HTTP server',
        :port => 8808, :gemdir => [], :daemon => false

  OptionParser.accept :Port do |port|
    if port =~ /\A\d+\z/ then
      port = Integer port
      raise OptionParser::InvalidArgument, "#{port}: not a port number" if
        port > 65535

      port
    else
      begin
        Socket.getservbyname port
      rescue SocketError
        raise OptionParser::InvalidArgument, "#{port}: no such named service"
      end
    end
  end

  add_option '-p', '--port=PORT', :Port,
             'port to listen on' do |port, options|
    options[:port] = port
  end

  add_option '-d', '--dir=GEMDIR',
             'directories from which to serve gems',
             'multiple directories may be provided' do |gemdir, options|
    options[:gemdir] << File.expand_path(gemdir)
  end

  add_option '--[no-]daemon', 'run as a daemon' do |daemon, options|
    options[:daemon] = daemon
  end

  add_option '-b', '--bind=HOST,HOST',
             'addresses to bind', Array do |address, options|
    options[:addresses] ||= []
    options[:addresses].push(*address)
  end

  add_option '-l', '--launch[=COMMAND]',
             'launches a browser window',
             "COMMAND defaults to 'start' on Windows",
             "and 'open' on all other platforms" do |launch, options|
    launch ||= Gem.win_platform? ? 'start' : 'open'
    options[:launch] = launch
  end
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/server_command.rb, line 80
def execute
  options[:gemdir] = Gem.path if options[:gemdir].empty?
  Gem::Server.run options
end


class Gem::Commands::SetupCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::SetupCommand

Installs RubyGems itself. This command is ordinarily only available from a RubyGems checkout or tarball.

In Files

  • lib/rubygems/commands/setup_command.rb

Parent

Gem::Command

Constants

HISTORY_HEADER
VERSION_MATCHER

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 11
def initialize
  require 'tmpdir'

  super 'setup', 'Install RubyGems',
        :format_executable => true, :document => %w[ri],
        :site_or_vendor => :sitelibdir,
        :destdir => '', :prefix => '', :previous_version => ''

  add_option '--previous-version=VERSION',
             'Previous version of rubygems',
             'Used for changelog processing' do |version, options|
    options[:previous_version] = version
  end

  add_option '--prefix=PREFIX',
             'Prefix path for installing RubyGems',
             'Will not affect gem repository location' do |prefix, options|
    options[:prefix] = File.expand_path prefix
  end

  add_option '--destdir=DESTDIR',
             'Root directory to install RubyGems into',
             'Mainly used for packaging RubyGems' do |destdir, options|
    options[:destdir] = File.expand_path destdir
  end

  add_option '--[no-]vendor',
             'Install into vendorlibdir not sitelibdir' do |vendor, options|
    options[:site_or_vendor] = vendor ? :vendorlibdir : :sitelibdir
  end

  add_option '--[no-]format-executable',
             'Makes `gem` match ruby',
             'If ruby is ruby18, gem will be gem18' do |value, options|
    options[:format_executable] = value
  end

  add_option '--[no-]document [TYPES]', Array,
             'Generate documentation for RubyGems.',
             'List the documentation types you wish to',
             'generate.  For example: rdoc,ri' do |value, options|
    options[:document] = case value
                         when nil   then %w[rdoc ri]
                         when false then []
                         else            value
                         end
  end

  add_option '--[no-]rdoc',
             'Generate RDoc documentation for RubyGems' do |value, options|
    if value then
      options[:document] << 'rdoc'
    else
      options[:document].delete 'rdoc'
    end

    options[:document].uniq!
  end

  add_option '--[no-]ri',
             'Generate RI documentation for RubyGems' do |value, options|
    if value then
      options[:document] << 'ri'
    else
      options[:document].delete 'ri'
    end

    options[:document].uniq!
  end

  @verbose = nil
end

Public Instance Methods

check_ruby_version() click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 84
def check_ruby_version
  required_version = Gem::Requirement.new '>= 1.8.7'

  unless required_version.satisfied_by? Gem.ruby_version then
    alert_error "Expected Ruby version #{required_version}, is #{Gem.ruby_version}"
    terminate_interaction 1
  end
end
execute() click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 115
def execute
  @verbose = Gem.configuration.really_verbose

  install_destdir = options[:destdir]

  unless install_destdir.empty? then
    ENV['GEM_HOME'] ||= File.join(install_destdir,
                                  Gem.default_dir.gsub(/^[a-zA-Z]:/, ''))
  end

  check_ruby_version

  require 'fileutils'
  if Gem.configuration.really_verbose then
    extend FileUtils::Verbose
  else
    extend FileUtils
  end

  lib_dir, bin_dir = make_destination_dirs install_destdir

  install_lib lib_dir

  install_executables bin_dir

  remove_old_bin_files bin_dir

  remove_old_lib_files lib_dir

  say "RubyGems #{Gem::VERSION} installed"

  uninstall_old_gemcutter

  documentation_success = install_rdoc

  say
  if @verbose then
    say "-" * 78
    say
  end

  if options[:previous_version].empty?
    options[:previous_version] = Gem::VERSION.sub(/[0-9]+$/, '0')
  end

  options[:previous_version] = Gem::Version.new(options[:previous_version])

  show_release_notes

  say
  say "-" * 78
  say

  say "RubyGems installed the following executables:"
  say @bin_file_names.map { |name| "\t#{name}\n" }
  say

  unless @bin_file_names.grep(/#{File::SEPARATOR}gem$/) then
    say "If `gem` was installed by a previous RubyGems installation, you may need"
    say "to remove it by hand."
    say
  end

  if documentation_success
    if options[:document].include? 'rdoc' then
      say "Rdoc documentation was installed. You may now invoke:"
      say "  gem server"
      say "and then peruse beautifully formatted documentation for your gems"
      say "with your web browser."
      say "If you do not wish to install this documentation in the future, use the"
      say "--no-document flag, or set it as the default in your ~/.gemrc file. See"
      say "'gem help env' for details."
      say
    end

    if options[:document].include? 'ri' then
      say "Ruby Interactive (ri) documentation was installed. ri is kind of like man "
      say "pages for ruby libraries. You may access it like this:"
      say "  ri Classname"
      say "  ri Classname.class_method"
      say "  ri Classname#instance_method"
      say "If you do not wish to install this documentation in the future, use the"
      say "--no-document flag, or set it as the default in your ~/.gemrc file. See"
      say "'gem help env' for details."
      say
    end
  end
end
generate_default_dirs(install_destdir) click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 341
def generate_default_dirs(install_destdir)
  prefix = options[:prefix]
  site_or_vendor = options[:site_or_vendor]

  if prefix.empty? then
    lib_dir = Gem::ConfigMap[site_or_vendor]
    bin_dir = Gem::ConfigMap[:bindir]
  else
    # Apple installed RubyGems into libdir, and RubyGems <= 1.1.0 gets
    # confused about installation location, so switch back to
    # sitelibdir/vendorlibdir.
    if defined?(APPLE_GEM_HOME) and
      # just in case Apple and RubyGems don't get this patched up proper.
      (prefix == Gem::ConfigMap[:libdir] or
       # this one is important
       prefix == File.join(Gem::ConfigMap[:libdir], 'ruby')) then
       lib_dir = Gem::ConfigMap[site_or_vendor]
       bin_dir = Gem::ConfigMap[:bindir]
    else
      lib_dir = File.join prefix, 'lib'
      bin_dir = File.join prefix, 'bin'
    end
  end

  unless install_destdir.empty? then
    lib_dir = File.join install_destdir, lib_dir.gsub(/^[a-zA-Z]:/, '')
    bin_dir = File.join install_destdir, bin_dir.gsub(/^[a-zA-Z]:/, '')
  end

  [lib_dir, bin_dir]
end
install_executables(bin_dir) click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 204
  def install_executables(bin_dir)
    say "Installing gem executable" if @verbose

    @bin_file_names = []

    Dir.chdir 'bin' do
      bin_files = Dir['*']

      bin_files.delete 'update_rubygems'

      bin_files.each do |bin_file|
        bin_file_formatted = if options[:format_executable] then
                               Gem.default_exec_format % bin_file
                             else
                               bin_file
                             end

        dest_file = File.join bin_dir, bin_file_formatted
        bin_tmp_file = File.join Dir.tmpdir, "#{bin_file}.#{$$}"

        begin
          bin = File.readlines bin_file
          bin[0] = "#!#{Gem.ruby}\n"

          File.open bin_tmp_file, 'w' do |fp|
            fp.puts bin.join
          end

          install bin_tmp_file, dest_file, :mode => 0755
          @bin_file_names << dest_file
        ensure
          rm bin_tmp_file
        end

        next unless Gem.win_platform?

        begin
          bin_cmd_file = File.join Dir.tmpdir, "#{bin_file}.bat"

          File.open bin_cmd_file, 'w' do |file|
            file.puts <<-TEXT
@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"#{File.basename(Gem.ruby).chomp('"')}" "#{dest_file}" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
@"#{File.basename(Gem.ruby).chomp('"')}" "%~dpn0" %*
TEXT
          end

          install bin_cmd_file, "#{dest_file}.bat", :mode => 0755
        ensure
          rm bin_cmd_file
        end
      end
    end
  end
install_file(file, dest_dir) click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 262
def install_file file, dest_dir
  dest_file = File.join dest_dir, file
  dest_dir = File.dirname dest_file
  mkdir_p dest_dir unless File.directory? dest_dir

  install file, dest_file, :mode => 0644
end
install_lib(lib_dir) click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 270
def install_lib(lib_dir)
  say "Installing RubyGems" if @verbose

  lib_files = rb_files_in 'lib'
  pem_files = pem_files_in 'lib'

  Dir.chdir 'lib' do
    lib_files.each do |lib_file|
      install_file lib_file, lib_dir
    end

    pem_files.each do |pem_file|
      install_file pem_file, lib_dir
    end
  end
end
install_rdoc() click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 287
def install_rdoc
  gem_doc_dir = File.join Gem.dir, 'doc'
  rubygems_name = "rubygems-#{Gem::VERSION}"
  rubygems_doc_dir = File.join gem_doc_dir, rubygems_name

  begin
    Gem.ensure_gem_subdirectories Gem.dir
  rescue SystemCallError
    # ignore
  end

  if File.writable? gem_doc_dir and
     (not File.exist? rubygems_doc_dir or
      File.writable? rubygems_doc_dir) then
    say "Removing old RubyGems RDoc and ri" if @verbose
    Dir[File.join(Gem.dir, 'doc', 'rubygems-[0-9]*')].each do |dir|
      rm_rf dir
    end

    require 'rubygems/rdoc'

    fake_spec = Gem::Specification.new 'rubygems', Gem::VERSION
    def fake_spec.full_gem_path
      File.expand_path '../../../..', __FILE__
    end

    generate_ri   = options[:document].include? 'ri'
    generate_rdoc = options[:document].include? 'rdoc'

    rdoc = Gem::RDoc.new fake_spec, generate_rdoc, generate_ri
    rdoc.generate

    return true
  elsif @verbose then
    say "Skipping RDoc generation, #{gem_doc_dir} not writable"
    say "Set the GEM_HOME environment variable if you want RDoc generated"
  end

  return false
end
make_destination_dirs(install_destdir) click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 328
def make_destination_dirs(install_destdir)
  lib_dir, bin_dir = Gem.default_rubygems_dirs

  unless lib_dir
    lib_dir, bin_dir = generate_default_dirs(install_destdir)
  end

  mkdir_p lib_dir
  mkdir_p bin_dir

  return lib_dir, bin_dir
end
pem_files_in(dir) click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 373
def pem_files_in dir
  Dir.chdir dir do
    Dir[File.join('**', '*pem')]
  end
end
rb_files_in(dir) click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 379
def rb_files_in dir
  Dir.chdir dir do
    Dir[File.join('**', '*rb')]
  end
end
remove_old_bin_files(bin_dir) click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 385
  def remove_old_bin_files(bin_dir)
    old_bin_files = {
      'gem_mirror' => 'gem mirror',
      'gem_server' => 'gem server',
      'gemlock' => 'gem lock',
      'gemri' => 'ri',
      'gemwhich' => 'gem which',
      'index_gem_repository.rb' => 'gem generate_index',
    }

    old_bin_files.each do |old_bin_file, new_name|
      old_bin_path = File.join bin_dir, old_bin_file
      next unless File.exist? old_bin_path

      deprecation_message = "`#{old_bin_file}` has been deprecated.  Use `#{new_name}` instead."

      File.open old_bin_path, 'w' do |fp|
        fp.write <<-EOF
#!#{Gem.ruby}

abort "#{deprecation_message}"
    EOF
      end

      next unless Gem.win_platform?

      File.open "#{old_bin_path}.bat", 'w' do |fp|
        fp.puts %Q{@ECHO.#{deprecation_message}}
      end
    end
  end
remove_old_lib_files(lib_dir) click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 417
def remove_old_lib_files lib_dir
  rubygems_dir = File.join lib_dir, 'rubygems'
  lib_files = rb_files_in 'lib/rubygems'

  old_lib_files = rb_files_in rubygems_dir

  to_remove = old_lib_files - lib_files

  to_remove.delete_if do |file|
    file.start_with? 'defaults'
  end

  Dir.chdir rubygems_dir do
    to_remove.each do |file|
      FileUtils.rm_f file

      warn "unable to remove old file #{file} please remove it by hand" if
        File.exist? file
    end
  end
end
show_release_notes() click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 439
def show_release_notes
  release_notes = File.join Dir.pwd, 'History.txt'

  release_notes =
    if File.exist? release_notes then
      history = File.read release_notes

      history.force_encoding Encoding::UTF_8 if
        Object.const_defined? :Encoding

      history = history.sub(/^# coding:.*?^=/, '')

      text = history.split(HISTORY_HEADER)
      text.shift # correct an off-by-one generated by split
      version_lines = history.scan(HISTORY_HEADER)
      versions = history.scan(VERSION_MATCHER).flatten.map do |x|
        Gem::Version.new(x)
      end

      history_string = ""

      until versions.length == 0 or
            versions.shift < options[:previous_version] do
        history_string += version_lines.shift + text.shift
      end

      history_string
    else
      "Oh-no! Unable to find release notes!"
    end

  say release_notes
end
uninstall_old_gemcutter() click to toggle source
# File lib/rubygems/commands/setup_command.rb, line 473
def uninstall_old_gemcutter
  require 'rubygems/uninstaller'

  ui = Gem::Uninstaller.new('gemcutter', :all => true, :ignore => true,
                            :version => '< 0.4')
  ui.uninstall
rescue Gem::InstallError
end


class Gem::Commands::SourcesCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::SourcesCommand

In Files

  • lib/rubygems/commands/sources_command.rb

Parent

Gem::Command

Included Modules

  • Gem::LocalRemoteOptions

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/sources_command.rb, line 10
def initialize
  require 'fileutils'

  super 'sources',
        'Manage the sources and cache file RubyGems uses to search for gems'

  add_option '-a', '--add SOURCE_URI', 'Add source' do |value, options|
    options[:add] = value
  end

  add_option '-l', '--list', 'List sources' do |value, options|
    options[:list] = value
  end

  add_option '-r', '--remove SOURCE_URI', 'Remove source' do |value, options|
    options[:remove] = value
  end

  add_option '-c', '--clear-all',
             'Remove all sources (clear the cache)' do |value, options|
    options[:clear_all] = value
  end

  add_option '-u', '--update', 'Update source cache' do |value, options|
    options[:update] = value
  end

  add_proxy_option
end

Public Instance Methods

defaults_str() click to toggle source
# File lib/rubygems/commands/sources_command.rb, line 40
def defaults_str
  '--list'
end
execute() click to toggle source
# File lib/rubygems/commands/sources_command.rb, line 44
  def execute
    options[:list] = !(options[:add] ||
                       options[:clear_all] ||
                       options[:remove] ||
                       options[:update])

    if options[:clear_all] then
      path = File.join Gem.user_home, '.gem', 'specs'
      FileUtils.rm_rf path

      unless File.exist? path then
        say "*** Removed specs cache ***"
      else
        unless File.writable? path then
          say "*** Unable to remove source cache (write protected) ***"
        else
          say "*** Unable to remove source cache ***"
        end

        terminate_interaction 1
      end
    end

    if source_uri = options[:add] then
      uri = URI source_uri

      if uri.scheme and uri.scheme.downcase == 'http' and
         uri.host.downcase == 'rubygems.org' then
        question = "https://rubygems.org is recommended for security over #{uri}

Do you want to add this insecure source?
".chomp

        terminate_interaction 1 unless ask_yes_no question
      end

      source = Gem::Source.new source_uri

      begin
        if Gem.sources.include? source_uri then
          say "source #{source_uri} already present in the cache"
        else
          source.load_specs :released
          Gem.sources << source
          Gem.configuration.write

          say "#{source_uri} added to sources"
        end
      rescue URI::Error, ArgumentError
        say "#{source_uri} is not a URI"
        terminate_interaction 1
      rescue Gem::RemoteFetcher::FetchError => e
        say "Error fetching #{source_uri}:\n\t#{e.message}"
        terminate_interaction 1
      end
    end

    if options[:remove] then
      source_uri = options[:remove]

      unless Gem.sources.include? source_uri then
        say "source #{source_uri} not present in cache"
      else
        Gem.sources.delete source_uri
        Gem.configuration.write

        say "#{source_uri} removed from sources"
      end
    end

    if options[:update] then
      Gem.sources.each_source do |src|
        src.load_specs :released
        src.load_specs :latest
      end

      say "source cache successfully updated"
    end

    if options[:list] then
      say "*** CURRENT SOURCES ***"
      say

      Gem.sources.each do |src|
        say src
      end
    end
  end


class Gem::Commands::SpecificationCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::SpecificationCommand

In Files

  • lib/rubygems/commands/specification_command.rb

Parent

Gem::Command

Included Modules

  • Gem::LocalRemoteOptions
  • Gem::VersionOption

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/specification_command.rb, line 11
def initialize
  Gem.load_yaml

  super 'specification', 'Display gem specification (in yaml)',
        :domain => :local, :version => Gem::Requirement.default,
        :format => :yaml

  add_version_option('examine')
  add_platform_option
  add_prerelease_option

  add_option('--all', 'Output specifications for all versions of',
             'the gem') do |value, options|
    options[:all] = true
  end

  add_option('--ruby', 'Output ruby format') do |value, options|
    options[:format] = :ruby
  end

  add_option('--yaml', 'Output YAML format') do |value, options|
    options[:format] = :yaml
  end

  add_option('--marshal', 'Output Marshal format') do |value, options|
    options[:format] = :marshal
  end

  add_local_remote_options
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/specification_command.rb, line 57
def execute
  specs = []
  gem = options[:args].shift

  unless gem then
    raise Gem::CommandLineError,
          "Please specify a gem name or file on the command line"
  end

  case v = options[:version]
  when String
    req = Gem::Requirement.create v
  when Gem::Requirement
    req = v
  else
    raise Gem::CommandLineError, "Unsupported version type: '#{v}'"
  end

  if !req.none? and options[:all]
    alert_error "Specify --all or -v, not both"
    terminate_interaction 1
  end

  if options[:all]
    dep = Gem::Dependency.new gem
  else
    dep = Gem::Dependency.new gem, req
  end

  field = get_one_optional_argument

  raise Gem::CommandLineError, "--ruby and FIELD are mutually exclusive" if
    field and options[:format] == :ruby

  if local? then
    if File.exist? gem then
      specs << Gem::Package.new(gem).spec rescue nil
    end

    if specs.empty? then
      specs.push(*dep.matching_specs)
    end
  end

  if remote? then
    dep.prerelease = options[:prerelease]
    found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dep

    specs.push(*found.map { |spec,| spec })
  end

  if specs.empty? then
    alert_error "No gem matching '#{dep}' found"
    terminate_interaction 1
  end

  unless options[:all] then
    specs = [specs.sort_by { |s| s.version }.last]
  end

  specs.each do |s|
    s = s.send field if field

    say case options[:format]
        when :ruby then s.to_ruby
        when :marshal then Marshal.dump s
        else s.to_yaml
        end

    say "\n"
  end
end


class Gem::Commands::StaleCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::StaleCommand

In Files

  • lib/rubygems/commands/stale_command.rb

Parent

Gem::Command

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/stale_command.rb, line 4
def initialize
  super('stale', 'List gems along with access times')
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/stale_command.rb, line 12
def execute
  gem_to_atime = {}
  Gem::Specification.each do |spec|
    name = spec.full_name
    Dir["#{spec.full_gem_path}/**/*.*"].each do |file|
      next if File.directory?(file)
      stat = File.stat(file)
      gem_to_atime[name] ||= stat.atime
      gem_to_atime[name] = stat.atime if gem_to_atime[name] < stat.atime
    end
  end

  gem_to_atime.sort_by { |_, atime| atime }.each do |name, atime|
    say "#{name} at #{atime.strftime '%c'}"
  end
end


class Gem::Commands::UninstallCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::UninstallCommand

Gem uninstaller command line tool

See `gem help uninstall`

In Files

  • lib/rubygems/commands/uninstall_command.rb

Parent

Gem::Command

Included Modules

  • Gem::VersionOption

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/uninstall_command.rb, line 14
def initialize
  super 'uninstall', 'Uninstall gems from the local repository',
        :version => Gem::Requirement.default, :user_install => true,
        :check_dev => false

  add_option('-a', '--[no-]all',
    'Uninstall all matching versions'
    ) do |value, options|
    options[:all] = value
  end

  add_option('-I', '--[no-]ignore-dependencies',
             'Ignore dependency requirements while',
             'uninstalling') do |value, options|
    options[:ignore] = value
  end

  add_option('-D', '--[no-]-check-development',
             'Check development dependencies while uninstalling',
             '(default: false)') do |value, options|
    options[:check_dev] = value
  end

  add_option('-x', '--[no-]executables',
               'Uninstall applicable executables without',
               'confirmation') do |value, options|
    options[:executables] = value
  end

  add_option('-i', '--install-dir DIR',
             'Directory to uninstall gem from') do |value, options|
    options[:install_dir] = File.expand_path(value)
  end

  add_option('-n', '--bindir DIR',
             'Directory to remove binaries from') do |value, options|
    options[:bin_dir] = File.expand_path(value)
  end

  add_option('--[no-]user-install',
             'Uninstall from user\s home directory',
             'in addition to GEM_HOME.') do |value, options|
    options[:user_install] = value
  end

  add_option('--[no-]format-executable',
             'Assume executable names match Ruby\s prefix and suffix.') do |value, options|
    options[:format_executable] = value
  end

  add_option('--[no-]force',
             'Uninstall all versions of the named gems',
             'ignoring dependencies') do |value, options|
    options[:force] = value
  end

  add_version_option
  add_platform_option
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/uninstall_command.rb, line 88
def execute
  # REFACTOR: stolen from cleanup_command
  deplist = Gem::DependencyList.new
  get_all_gem_names.uniq.each do |name|
    Gem::Specification.find_all_by_name(name).each do |spec|
      deplist.add spec
    end
  end

  deps = deplist.strongly_connected_components.flatten.reverse

  deps.map(&:name).uniq.each do |gem_name|
    begin
      Gem::Uninstaller.new(gem_name, options).uninstall
    rescue Gem::GemNotInHomeException => e
      spec = e.spec
      alert("In order to remove #{spec.name}, please execute:\n" +
            "\tgem uninstall #{spec.name} --install-dir=#{spec.installation_path}")
    end
  end
end


class Gem::Commands::UnpackCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::UnpackCommand

In Files

  • lib/rubygems/commands/unpack_command.rb

Parent

Gem::Command

Included Modules

  • Gem::VersionOption

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/unpack_command.rb, line 10
def initialize
  require 'fileutils'

  super 'unpack', 'Unpack an installed gem to the current directory',
        :version => Gem::Requirement.default,
        :target  => Dir.pwd

  add_option('--target=DIR',
             'target directory for unpacking') do |value, options|
    options[:target] = value
  end

  add_option('--spec', 'unpack the gem specification') do |value, options|
    options[:spec] = true
  end

  add_version_option
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/unpack_command.rb, line 46
def execute
  get_all_gem_names.each do |name|
    dependency = Gem::Dependency.new name, options[:version]
    path = get_path dependency

    unless path then
      alert_error "Gem '#{name}' not installed nor fetchable."
      next
    end

    if @options[:spec] then
      spec, metadata = get_metadata path

      if metadata.nil? then
        alert_error "--spec is unsupported on '#{name}' (old format gem)"
        next
      end

      spec_file = File.basename spec.spec_file

      open spec_file, 'w' do |io|
        io.write metadata
      end
    else
      basename = File.basename path, '.gem'
      target_dir = File.expand_path basename, options[:target]

      package = Gem::Package.new path
      package.extract_files target_dir

      say "Unpacked gem: '#{target_dir}'"
    end
  end
end
find_in_cache(filename) click to toggle source

Find cached filename in Gem.path. Returns nil if the file cannot be found.

# File lib/rubygems/commands/unpack_command.rb, line 88
def find_in_cache(filename)
  Gem.path.each do |path|
    this_path = File.join(path, "cache", filename)
    return this_path if File.exist? this_path
  end

  return nil
end
get_metadata(path) click to toggle source

Extracts the Gem::Specification and raw metadata from the .gem file at path.

# File lib/rubygems/commands/unpack_command.rb, line 142
def get_metadata path
  format = Gem::Package.new path
  spec = format.spec

  metadata = nil

  open path, Gem.binary_mode do |io|
    tar = Gem::Package::TarReader.new io
    tar.each_entry do |entry|
      case entry.full_name
      when 'metadata' then
        metadata = entry.read
      when 'metadata.gz' then
        metadata = Gem.gunzip entry.read
      end
    end
  end

  return spec, metadata
end
get_path(dependency) click to toggle source

Return the full path to the cached gem file matching the given name and version requirement. Returns 'nil' if no match.

Example:

get_path 'rake', '> 0.4' # "/usr/lib/ruby/gems/1.8/cache/rake-0.4.2.gem"
get_path 'rake', '< 0.1' # nil
get_path 'rak'           # nil (exact name required)
# File lib/rubygems/commands/unpack_command.rb, line 114
def get_path dependency
  return dependency.name if dependency.name =~ /\.gem$/

  specs = dependency.matching_specs

  selected = specs.sort_by { |s| s.version }.last # HACK: hunt last down

  return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless
    selected

  return unless dependency.name =~ /^#{selected.name}$/

  # We expect to find (basename).gem in the 'cache' directory.  Furthermore,
  # the name match must be exact (ignoring case).

  path = find_in_cache File.basename selected.cache_file

  return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless path

  path
end


class Gem::Commands::UpdateCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::UpdateCommand

In Files

  • lib/rubygems/commands/update_command.rb

Parent

Gem::Command

Included Modules

  • Gem::InstallUpdateOptions
  • Gem::LocalRemoteOptions
  • Gem::VersionOption

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/update_command.rb, line 19
def initialize
  super 'update', 'Update installed gems to the latest version',
    :document => %w[rdoc ri],
    :force    => false

  add_install_update_options

  OptionParser.accept Gem::Version do |value|
    Gem::Version.new value

    value
  end

  add_option('--system [VERSION]', Gem::Version,
             'Update the RubyGems system software') do |value, options|
    value = true unless value

    options[:system] = value
  end

  add_local_remote_options
  add_platform_option
  add_prerelease_option "as update targets"

  @updated   = []
  @installer = nil
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/update_command.rb, line 59
def execute
  hig = {}

  if options[:system] then
    update_rubygems
    return
  else
    say "Updating installed gems"

    hig = {} # highest installed gems

    Gem::Specification.each do |spec|
      if hig[spec.name].nil? or hig[spec.name].version < spec.version then
        hig[spec.name] = spec
      end
    end
  end

  gems_to_update = which_to_update hig, options[:args].uniq

  updated = update_gems gems_to_update

  if updated.empty? then
    say "Nothing to update"
  else
    say "Gems updated: #{updated.map { |spec| spec.name }.join ' '}"
  end
end
update_gem(name, version = Gem::Requirement.default) click to toggle source
# File lib/rubygems/commands/update_command.rb, line 88
def update_gem name, version = Gem::Requirement.default
  return if @updated.any? { |spec| spec.name == name }

  @installer ||= Gem::DependencyInstaller.new options

  success = false

  say "Updating #{name}"
  begin
    @installer.install name, Gem::Requirement.new(version)
    success = true
  rescue Gem::InstallError => e
    alert_error "Error installing #{name}:\n\t#{e.message}"
    success = false
  end

  @installer.installed_gems.each do |spec|
    @updated << spec
  end
end
update_gems(gems_to_update) click to toggle source
# File lib/rubygems/commands/update_command.rb, line 109
def update_gems gems_to_update
  gems_to_update.uniq.sort.each do |(name, version)|
    update_gem name, version
  end

  @updated
end
update_rubygems() click to toggle source

Update RubyGems software to the latest version.

# File lib/rubygems/commands/update_command.rb, line 120
def update_rubygems
  unless options[:args].empty? then
    alert_error "Gem names are not allowed with the --system option"
    terminate_interaction 1
  end

  options[:user_install] = false

  # TODO: rename version and other variable name conflicts
  # TODO: get rid of all this indirection on name and other BS

  version = options[:system]
  if version == true then
    version     = Gem::Version.new     Gem::VERSION
    requirement = Gem::Requirement.new ">= #{Gem::VERSION}"
  else
    version     = Gem::Version.new     version
    requirement = Gem::Requirement.new version
  end

  rubygems_update         = Gem::Specification.new
  rubygems_update.name    = 'rubygems-update'
  rubygems_update.version = version

  hig = {
    'rubygems-update' => rubygems_update
  }

  gems_to_update = which_to_update hig, options[:args], :system
  name, up_ver   = gems_to_update.first
  current_ver    = Gem.rubygems_version

  target = if options[:system] == true then
             up_ver
           else
             version
           end

  if current_ver == target then
    # if options[:system] != true and version == current_ver then
    say "Latest version currently installed. Aborting."
    terminate_interaction
  end

  update_gem name, target

  installed_gems = Gem::Specification.find_all_by_name 'rubygems-update', requirement
  version        = installed_gems.last.version

  args = []
  args << '--prefix' << Gem.prefix if Gem.prefix
  # TODO use --document for >= 1.9 , --no-rdoc --no-ri < 1.9
  args << '--no-rdoc' unless options[:document].include? 'rdoc'
  args << '--no-ri'   unless options[:document].include? 'ri'
  args << '--no-format-executable' if options[:no_format_executable]

  update_dir = File.join Gem.dir, 'gems', "rubygems-update-#{version}"

  Dir.chdir update_dir do
    say "Installing RubyGems #{version}"
    setup_cmd = "#{Gem.ruby} setup.rb #{args.join ' '}"

    # Make sure old rubygems isn't loaded
    old = ENV["RUBYOPT"]
    ENV.delete("RUBYOPT") if old
    installed = system setup_cmd
    say "RubyGems system software updated" if installed
    ENV["RUBYOPT"] = old if old
  end
end
which_to_update(highest_installed_gems, gem_names, system = false) click to toggle source
# File lib/rubygems/commands/update_command.rb, line 191
def which_to_update highest_installed_gems, gem_names, system = false
  result = []

  highest_installed_gems.each do |l_name, l_spec|
    next if not gem_names.empty? and
            gem_names.all? { |name| /#{name}/ !~ l_spec.name }

    dependency = Gem::Dependency.new l_spec.name, "> #{l_spec.version}"
    dependency.prerelease = options[:prerelease]

    fetcher = Gem::SpecFetcher.fetcher

    spec_tuples, _ = fetcher.search_for_dependency dependency

    matching_gems = spec_tuples.select do |g,_|
      g.name == l_name and g.match_platform?
    end

    highest_remote_gem = matching_gems.sort_by { |g,_| g.version }.last

    highest_remote_gem ||= [Gem::NameTuple.null]
    highest_remote_ver = highest_remote_gem.first.version

    if system or (l_spec.version < highest_remote_ver) then
      result << [l_spec.name, [l_spec.version, highest_remote_ver].max]
    end
  end

  result
end


class Gem::Commands::WhichCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::WhichCommand

In Files

  • lib/rubygems/commands/which_command.rb

Parent

Gem::Command

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/which_command.rb, line 4
def initialize
  super 'which', 'Find the location of a library file you can require',
        :search_gems_first => false, :show_all => false

  add_option '-a', '--[no-]all', 'show all matching files' do |show_all, options|
    options[:show_all] = show_all
  end

  add_option '-g', '--[no-]gems-first',
             'search gems before non-gems' do |gems_first, options|
    options[:search_gems_first] = gems_first
  end
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/which_command.rb, line 26
def execute
  found = false

  options[:args].each do |arg|
    arg = arg.sub(/#{Regexp.union(*Gem.suffixes)}$/, '')
    dirs = $LOAD_PATH

    spec = Gem::Specification.find_by_path arg

    if spec then
      if options[:search_gems_first] then
        dirs = gem_paths(spec) + $LOAD_PATH
      else
        dirs = $LOAD_PATH + gem_paths(spec)
      end
    end

    # TODO: this is totally redundant and stupid
    paths = find_paths arg, dirs

    if paths.empty? then
      alert_error "Can't find ruby library file or shared library #{arg}"
    else
      say paths
      found = true
    end
  end

  terminate_interaction 1 unless found
end
find_paths(package_name, dirs) click to toggle source
# File lib/rubygems/commands/which_command.rb, line 57
def find_paths(package_name, dirs)
  result = []

  dirs.each do |dir|
    Gem.suffixes.each do |ext|
      full_path = File.join dir, "#{package_name}#{ext}"
      if File.exist? full_path and not File.directory? full_path then
        result << full_path
        return result unless options[:show_all]
      end
    end
  end

  result
end
gem_paths(spec) click to toggle source
# File lib/rubygems/commands/which_command.rb, line 73
def gem_paths(spec)
  spec.require_paths.collect { |d| File.join spec.full_gem_path, d }
end


class Gem::Commands::YankCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Commands::YankCommand

In Files

  • lib/rubygems/commands/yank_command.rb

Parent

Gem::Command

Included Modules

  • Gem::LocalRemoteOptions
  • Gem::VersionOption
  • Gem::GemcutterUtilities

Public Class Methods

new() click to toggle source
# File lib/rubygems/commands/yank_command.rb, line 23
def initialize
  super 'yank', description

  add_version_option("remove")
  add_platform_option("remove")

  add_option('--undo') do |value, options|
    options[:undo] = true
  end

  add_option('-k', '--key KEY_NAME',
             'Use API key from your gem credentials file') do |value, options|
    options[:key] = value
  end
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/yank_command.rb, line 39
def execute
  sign_in

  version   = get_version_from_requirements(options[:version])
  platform  = get_platform_from_requirements(options)
  api_key   = Gem.configuration.rubygems_api_key
  api_key   = Gem.configuration.api_keys[options[:key].to_sym] if options[:key]

  if version then
    if options[:undo] then
      unyank_gem(version, platform, api_key)
    else
      yank_gem(version, platform, api_key)
    end
  else
    say "A version argument is required: #{usage}"
    terminate_interaction
  end
end
unyank_gem(version, platform, api_key) click to toggle source
# File lib/rubygems/commands/yank_command.rb, line 64
def unyank_gem(version, platform, api_key)
  say "Unyanking gem from #{host}..."
  yank_api_request(:put, version, platform, "api/v1/gems/unyank", api_key)
end
yank_gem(version, platform, api_key) click to toggle source
# File lib/rubygems/commands/yank_command.rb, line 59
def yank_gem(version, platform, api_key)
  say "Yanking gem from #{self.host}..."
  yank_api_request(:delete, version, platform, "api/v1/gems/yank", api_key)
end


class Gem::ConfigFile - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::ConfigFile

Gem::ConfigFile RubyGems options and gem command options from gemrc.

gemrc is a YAML file that uses strings to match gem command arguments and symbols to match RubyGems options.

Gem command arguments use a String key that matches the command name and allow you to specify default arguments:

install: --no-rdoc --no-ri
update: --no-rdoc --no-ri

You can use gem: to set default arguments for all commands.

RubyGems options use symbol keys. Valid options are:

:backtrace

See backtrace

:sources

Sets Gem.sources

:verbose

See verbose

gemrc files may exist in various locations and are read and merged in the following order:

  • system wide (/etc/gemrc)

  • per user (~/.gemrc)

  • per environment (gemrc files listed in the GEMRC environment variable)

In Files

  • lib/rubygems/config_file.rb

Parent

Object

Included Modules

  • Gem::UserInteraction

Constants

DEFAULT_BACKTRACE
DEFAULT_BULK_THRESHOLD
DEFAULT_UPDATE_SOURCES
DEFAULT_VERBOSITY
OPERATING_SYSTEM_DEFAULTS

For Ruby packagers to set configuration defaults. Set in rubygems/defaults/operating_system.rb

PLATFORM_DEFAULTS

For Ruby implementers to set configuration defaults. Set in rubygems/defaults/#{RUBY_ENGINE}.rb

SYSTEM_WIDE_CONFIG_FILE

Attributes

args[R]

List of arguments supplied to the config file object.

backtrace[W]

True if we print backtraces on errors.

bulk_threshold[RW]

Bulk threshold value. If the number of missing gems are above this threshold value, then a bulk download technique is used. (deprecated)

disable_default_gem_server[RW]

True if we want to force specification of gem server when pushing a gem

hash[R]
home[RW]

Where to install gems (deprecated)

path[RW]

Where to look for gems (deprecated)

ssl_ca_cert[R]

Path name of directory or file of openssl CA certificate, used for remote https connection

ssl_verify_mode[R]

openssl verify mode value, used for remote https connection

update_sources[RW]

True if we want to update the SourceInfoCache every time, false otherwise

verbose[RW]

Verbose level of output:

  • false – No output

  • true – Normal output

  • :loud – Extra output

Public Class Methods

new(args) click to toggle source

Create the config file object. args is the list of arguments from the command line.

The following command line options are handled early here rather than later at the time most command options are processed.

--config-file, --config-file==NAME

Obviously these need to be handled by the ConfigFile object to ensure we get the right config file.

--backtrace

Backtrace needs to be turned on early so that errors before normal option parsing can be properly handled.

--debug

Enable Ruby level debug messages. Handled early for the same reason as –backtrace.

# File lib/rubygems/config_file.rb, line 165
def initialize(args)
  @config_file_name = nil
  need_config_file_name = false

  arg_list = []

  args.each do |arg|
    if need_config_file_name then
      @config_file_name = arg
      need_config_file_name = false
    elsif arg =~ /^--config-file=(.*)/ then
      @config_file_name = $1
    elsif arg =~ /^--config-file$/ then
      need_config_file_name = true
    else
      arg_list << arg
    end
  end

  @backtrace = DEFAULT_BACKTRACE
  @bulk_threshold = DEFAULT_BULK_THRESHOLD
  @verbose = DEFAULT_VERBOSITY
  @update_sources = DEFAULT_UPDATE_SOURCES

  operating_system_config = Marshal.load Marshal.dump(OPERATING_SYSTEM_DEFAULTS)
  platform_config = Marshal.load Marshal.dump(PLATFORM_DEFAULTS)
  system_config = load_file SYSTEM_WIDE_CONFIG_FILE
  user_config = load_file config_file_name.dup.untaint
  environment_config = (ENV['GEMRC'] || '').split(/[:;]/).inject({}) do |result, file|
    result.merge load_file file
  end

  @hash = operating_system_config.merge platform_config
  @hash = @hash.merge system_config
  @hash = @hash.merge user_config
  @hash = @hash.merge environment_config

  # HACK these override command-line args, which is bad
  @backtrace                  = @hash[:backtrace]                  if @hash.key? :backtrace
  @bulk_threshold             = @hash[:bulk_threshold]             if @hash.key? :bulk_threshold
  @home                       = @hash[:gemhome]                    if @hash.key? :gemhome
  @path                       = @hash[:gempath]                    if @hash.key? :gempath
  @update_sources             = @hash[:update_sources]             if @hash.key? :update_sources
  @verbose                    = @hash[:verbose]                    if @hash.key? :verbose
  @disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server

  @ssl_verify_mode  = @hash[:ssl_verify_mode]  if @hash.key? :ssl_verify_mode
  @ssl_ca_cert      = @hash[:ssl_ca_cert]      if @hash.key? :ssl_ca_cert

  @api_keys         = nil
  @rubygems_api_key = nil

  Gem.sources = @hash[:sources] if @hash.key? :sources
  handle_arguments arg_list
end

Public Instance Methods

[](key) click to toggle source

Return the configuration information for key.

# File lib/rubygems/config_file.rb, line 438
def [](key)
  @hash[key.to_s]
end
[]=(key, value) click to toggle source

Set configuration option key to value.

# File lib/rubygems/config_file.rb, line 443
def []=(key, value)
  @hash[key.to_s] = value
end
api_keys() click to toggle source

Hash of RubyGems.org and alternate API keys

# File lib/rubygems/config_file.rb, line 225
def api_keys
  load_api_keys unless @api_keys

  @api_keys
end
backtrace() click to toggle source

True if the backtrace option has been specified, or debug is on.

# File lib/rubygems/config_file.rb, line 335
def backtrace
  @backtrace or $DEBUG
end
check_credentials_permissions() click to toggle source

Checks the permissions of the credentials file. If they are not 0600 an error message is displayed and RubyGems aborts.

# File lib/rubygems/config_file.rb, line 235
  def check_credentials_permissions
    return if Gem.win_platform? # windows doesn't write 0600 as 0600
    return unless File.exist? credentials_path

    existing_permissions = File.stat(credentials_path).mode & 0777

    return if existing_permissions == 0600

    alert_error <<-ERROR
Your gem push credentials file located at:

\t#{credentials_path}

has file permissions of 0#{existing_permissions.to_s 8} but 0600 is required.

You should reset your credentials at:

\thttps://rubygems.org/profile/edit

if you believe they were disclosed to a third party.
    ERROR

    terminate_interaction 1
  end
config_file_name() click to toggle source

The name of the configuration file.

# File lib/rubygems/config_file.rb, line 340
def config_file_name
  @config_file_name || Gem.config_file
end
credentials_path() click to toggle source

Location of RubyGems.org credentials

# File lib/rubygems/config_file.rb, line 263
def credentials_path
  File.join Gem.user_home, '.gem', 'credentials'
end
each() { |:update_sources, update_sources| ... } click to toggle source

Delegates to @hash

# File lib/rubygems/config_file.rb, line 345
def each(&block)
  hash = @hash.dup
  hash.delete :update_sources
  hash.delete :verbose
  hash.delete :backtrace
  hash.delete :bulk_threshold

  yield :update_sources, @update_sources
  yield :verbose, @verbose
  yield :backtrace, @backtrace
  yield :bulk_threshold, @bulk_threshold

  yield 'config_file_name', @config_file_name if @config_file_name

  hash.each(&block)
end
handle_arguments(arg_list) click to toggle source

Handle the command arguments.

# File lib/rubygems/config_file.rb, line 363
def handle_arguments(arg_list)
  @args = []

  arg_list.each do |arg|
    case arg
    when /^--(backtrace|traceback)$/ then
      @backtrace = true
    when /^--debug$/ then
      $DEBUG = true
    else
      @args << arg
    end
  end
end
load_api_keys() click to toggle source
# File lib/rubygems/config_file.rb, line 267
def load_api_keys
  check_credentials_permissions

  @api_keys = if File.exist? credentials_path then
                load_file(credentials_path)
              else
                @hash
              end

  if @api_keys.key? :rubygems_api_key then
    @rubygems_api_key    = @api_keys[:rubygems_api_key]
    @api_keys[:rubygems] = @api_keys.delete :rubygems_api_key unless
      @api_keys.key? :rubygems
  end
end
load_file(filename) click to toggle source
# File lib/rubygems/config_file.rb, line 313
def load_file(filename)
  Gem.load_yaml

  return {} unless filename and File.exist? filename

  begin
    content = YAML.load(File.read(filename))
    unless content.kind_of? Hash
      warn "Failed to load #{filename} because it doesn't contain valid YAML hash"
      return {}
    end
    return content
  rescue ArgumentError
    warn "Failed to load #{filename}"
  rescue Errno::EACCES
    warn "Failed to load #{filename} due to permissions problem."
  end

  {}
end
really_verbose() click to toggle source

Really verbose mode gives you extra output.

# File lib/rubygems/config_file.rb, line 379
def really_verbose
  case verbose
  when true, false, nil then
    false
  else
    true
  end
end
rubygems_api_key() click to toggle source

Returns the RubyGems.org API key

# File lib/rubygems/config_file.rb, line 286
def rubygems_api_key
  load_api_keys unless @rubygems_api_key

  @rubygems_api_key
end
rubygems_api_key=(api_key) click to toggle source

Sets the RubyGems.org API key to api_key

# File lib/rubygems/config_file.rb, line 295
def rubygems_api_key= api_key
  check_credentials_permissions

  config = load_file(credentials_path).merge(:rubygems_api_key => api_key)

  dirname = File.dirname credentials_path
  Dir.mkdir(dirname) unless File.exist? dirname

  Gem.load_yaml

  permissions = 0600 & (~File.umask)
  File.open(credentials_path, 'w', permissions) do |f|
    f.write config.to_yaml
  end

  @rubygems_api_key = api_key
end
write() click to toggle source

Writes out this config file, replacing its source.

# File lib/rubygems/config_file.rb, line 431
def write
  open config_file_name, 'w' do |io|
    io.write to_yaml
  end
end


class Gem::ConsoleUI - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::ConsoleUI

Subclass of StreamUI that instantiates the user interaction using STDIN, STDOUT, and STDERR.

In Files

  • lib/rubygems/user_interaction.rb

Parent

Gem::StreamUI

Public Class Methods

new() click to toggle source
# File lib/rubygems/user_interaction.rb, line 541
def initialize
  super STDIN, STDOUT, STDERR, true
end


module Gem::DefaultUserInteraction - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::DefaultUserInteraction

When rubygems/test_case is required the default user interaction is a MockGemUi.

Module that defines the default UserInteraction. Any class including this module will have access to the ui method that returns the default UI.

In Files

  • lib/rubygems/test_case.rb
  • lib/rubygems/user_interaction.rb

Public Class Methods

ui() click to toggle source

Return the default UI.

# File lib/rubygems/user_interaction.rb, line 22
def self.ui
  @ui ||= Gem::ConsoleUI.new
end
ui=(new_ui) click to toggle source

Set the default UI. If the default UI is never explicitly set, a simple console based UserInteraction will be used automatically.

# File lib/rubygems/user_interaction.rb, line 30
def self.ui=(new_ui)
  @ui = new_ui
end
use_ui(new_ui) { || ... } click to toggle source

Use new_ui for the duration of block.

# File lib/rubygems/user_interaction.rb, line 37
def self.use_ui(new_ui)
  old_ui = @ui
  @ui = new_ui
  yield
ensure
  @ui = old_ui
end

Public Instance Methods

ui() click to toggle source

See ::ui

# File lib/rubygems/user_interaction.rb, line 48
def ui
  Gem::DefaultUserInteraction.ui
end
ui=(new_ui) click to toggle source

See ::ui=

# File lib/rubygems/user_interaction.rb, line 55
def ui=(new_ui)
  Gem::DefaultUserInteraction.ui = new_ui
end
use_ui(new_ui, &block) click to toggle source

See ::use_ui

# File lib/rubygems/user_interaction.rb, line 62
def use_ui(new_ui, &block)
  Gem::DefaultUserInteraction.use_ui(new_ui, &block)
end


class Gem::Dependency - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Dependency

In Files

  • lib/rubygems/dependency.rb

Parent

Object

Constants

TYPES

Valid dependency types.

Attributes

name[RW]

Dependency name or regular expression.

prerelease[W]

Allows you to force this dependency to be a prerelease.

Public Class Methods

new(name, *requirements) click to toggle source

Constructs a dependency with name and requirements. The last argument can optionally be the dependency type, which defaults to :runtime.

# File lib/rubygems/dependency.rb, line 37
def initialize name, *requirements
  case name
  when String then # ok
  when Regexp then
    msg = ["NOTE: Dependency.new w/ a regexp is deprecated.",
           "Dependency.new called from #{Gem.location_of_caller.join(":")}"]
    warn msg.join("\n") unless Gem::Deprecate.skip
  else
    raise ArgumentError,
          "dependency name must be a String, was #{name.inspect}"
  end

  type         = Symbol === requirements.last ? requirements.pop : :runtime
  requirements = requirements.first if 1 == requirements.length # unpack

  unless TYPES.include? type
    raise ArgumentError, "Valid types are #{TYPES.inspect}, " +
                         "not #{type.inspect}"
  end

  @name        = name
  @requirement = Gem::Requirement.create requirements
  @type        = type
  @prerelease  = false

  # This is for Marshal backwards compatibility. See the comments in
  # +requirement+ for the dirty details.

  @version_requirements = @requirement
end

Public Instance Methods

<=>(other) click to toggle source

Dependencies are ordered by name.

# File lib/rubygems/dependency.rb, line 178
def <=> other
  self.name <=> other.name
end
=~(other) click to toggle source

Uses this dependency as a pattern to compare to other. This dependency will match if the name matches the other's name, and other has only an equal version requirement that satisfies this dependency.

# File lib/rubygems/dependency.rb, line 188
def =~ other
  unless Gem::Dependency === other
    return unless other.respond_to?(:name) && other.respond_to?(:version)
    other = Gem::Dependency.new other.name, other.version
  end

  return false unless name === other.name

  reqs = other.requirement.requirements

  return false unless reqs.length == 1
  return false unless reqs.first.first == '='

  version = reqs.first.last

  requirement.satisfied_by? version
end
latest_version?() click to toggle source

Is this dependency simply asking for the latest version of a gem?

# File lib/rubygems/dependency.rb, line 97
def latest_version?
  @requirement.none?
end
match?(obj, version=nil) click to toggle source

DOC: this method needs either documented or :nodoc'd

# File lib/rubygems/dependency.rb, line 208
def match? obj, version=nil
  if !version
    name = obj.name
    version = obj.version
  else
    name = obj
  end

  return false unless self.name === name
  return true if requirement.none?

  requirement.satisfied_by? Gem::Version.new(version)
end
matches_spec?(spec) click to toggle source

DOC: this method needs either documented or :nodoc'd

# File lib/rubygems/dependency.rb, line 224
def matches_spec? spec
  return false unless name === spec.name
  return true  if requirement.none?

  requirement.satisfied_by?(spec.version)
end
matching_specs(platform_only = false) click to toggle source

DOC: this method needs either documented or :nodoc'd

# File lib/rubygems/dependency.rb, line 252
def matching_specs platform_only = false
  matches = Gem::Specification.find_all { |spec|
    self.name === spec.name and # TODO: == instead of ===
      requirement.satisfied_by? spec.version
  }

  if platform_only
    matches.reject! { |spec|
      not Gem::Platform.match spec.platform
    }
  end

  matches = matches.sort_by { |s| s.sort_obj } # HACK: shouldn't be needed
end
merge(other) click to toggle source

Merges the requirements of other into this dependency

# File lib/rubygems/dependency.rb, line 234
def merge other
  unless name == other.name then
    raise ArgumentError,
          "#{self} and #{other} have different names"
  end

  default = Gem::Requirement.default
  self_req  = self.requirement
  other_req = other.requirement

  return self.class.new name, self_req  if other_req == default
  return self.class.new name, other_req if self_req  == default

  self.class.new name, self_req.as_list.concat(other_req.as_list)
end
prerelease?() click to toggle source

Does this dependency require a prerelease?

# File lib/rubygems/dependency.rb, line 89
def prerelease?
  @prerelease || requirement.prerelease?
end
requirement() click to toggle source

What does this dependency require?

# File lib/rubygems/dependency.rb, line 119
def requirement
  return @requirement if defined?(@requirement) and @requirement

  # @version_requirements and @version_requirement are legacy ivar
  # names, and supported here because older gems need to keep
  # working and Dependency doesn't implement marshal_dump and
  # marshal_load. In a happier world, this would be an
  # attr_accessor. The horrifying instance_variable_get you see
  # below is also the legacy of some old restructurings.
  #
  # Note also that because of backwards compatibility (loading new
  # gems in an old RubyGems installation), we can't add explicit
  # marshaling to this class until we want to make a big
  # break. Maybe 2.0.
  #
  # Children, define explicit marshal and unmarshal behavior for
  # public classes. Marshal formats are part of your public API.

  # REFACTOR: See above

  if defined?(@version_requirement) && @version_requirement
    version = @version_requirement.instance_variable_get :@version
    @version_requirement  = nil
    @version_requirements = Gem::Requirement.new version
  end

  @requirement = @version_requirements if defined?(@version_requirements)
end
requirements_list() click to toggle source

DOC: this method needs documentation or :nodoc''d

# File lib/rubygems/dependency.rb, line 149
def requirements_list
  requirement.as_list
end
specific?() click to toggle source

True if the dependency will not always match the latest version.

# File lib/rubygems/dependency.rb, line 270
def specific?
  @requirement.specific?
end
to_spec() click to toggle source

DOC: this method needs either documented or :nodoc'd

# File lib/rubygems/dependency.rb, line 306
def to_spec
  matches = self.to_specs

  matches.find { |spec| spec.activated? } or matches.last
end
to_specs() click to toggle source

DOC: this method needs either documented or :nodoc'd

# File lib/rubygems/dependency.rb, line 276
def to_specs
  matches = matching_specs true

  # TODO: check Gem.activated_spec[self.name] in case matches falls outside

  if matches.empty? then
    specs = Gem::Specification.find_all { |s|
              s.name == name
            }.map { |x| x.full_name }

    if specs.empty?
      total = Gem::Specification.to_a.size
      error = Gem::LoadError.new            "Could not find '#{name}' (#{requirement}) among #{total} total gem(s)"
    else
      error = Gem::LoadError.new            "Could not find '#{name}' (#{requirement}) - did find: [#{specs.join ','}]"
    end
    error.name        = self.name
    error.requirement = self.requirement
    raise error
  end

  # TODO: any other resolver validations should go here

  matches
end
type() click to toggle source

Dependency type.

# File lib/rubygems/dependency.rb, line 164
def type
  @type ||= :runtime
end


class Gem::DependencyError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyError

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::DependencyInstaller - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyInstaller

Installs a gem along with all its dependencies from local and remote gems.

In Files

  • lib/rubygems/dependency_installer.rb

Parent

Object

Included Modules

  • Gem::UserInteraction

Constants

DEFAULT_OPTIONS

Attributes

document[R]

Documentation types. For use by the Gem.done_installing hook

errors[R]
gems_to_install[R]
installed_gems[R]

Public Class Methods

new(options = {}) click to toggle source

Creates a new installer instance.

Options are:

:cache_dir

Alternate repository path to store .gem files in.

:domain

:local, :remote, or :both. :local only searches gems in the current directory. :remote searches only gems in Gem.sources. :both searches both.

:env_shebang

See Gem::Installer.new.

:force

See Gem::Installer#install.

:format_executable

See Gem::Installer#initialize.

:ignore_dependencies

Don't install any dependencies.

:install_dir

See Gem::Installer#install.

:prerelease

Allow prerelease versions. See install.

:security_policy

See Gem::Installer.new and Gem::Security.

:user_install

See Gem::Installer.new

:wrappers

See Gem::Installer.new

:build_args

See Gem::Installer.new

# File lib/rubygems/dependency_installer.rb, line 59
def initialize(options = {})
  @install_dir = options[:install_dir] || Gem.dir

  if options[:install_dir] then
    # HACK shouldn't change the global settings, needed for -i behavior
    # maybe move to the install command?  See also github #442
    Gem::Specification.dirs = @install_dir
  end

  options = DEFAULT_OPTIONS.merge options

  @bin_dir             = options[:bin_dir]
  @dev_shallow         = options[:dev_shallow]
  @development         = options[:development]
  @document            = options[:document]
  @domain              = options[:domain]
  @env_shebang         = options[:env_shebang]
  @force               = options[:force]
  @format_executable   = options[:format_executable]
  @ignore_dependencies = options[:ignore_dependencies]
  @prerelease          = options[:prerelease]
  @security_policy     = options[:security_policy]
  @user_install        = options[:user_install]
  @wrappers            = options[:wrappers]
  @build_args          = options[:build_args]
  @build_docs_in_background = options[:build_docs_in_background]

  # Indicates that we should not try to update any deps unless
  # we absolutely must.
  @minimal_deps        = options[:minimal_deps]

  @available      = nil
  @installed_gems = []
  @toplevel_specs = nil

  @cache_dir = options[:cache_dir] || @install_dir

  # Set with any errors that SpecFetcher finds while search through
  # gemspecs for a dep
  @errors = nil
end

Public Instance Methods

add_found_dependencies(to_do, dependency_list) click to toggle source
# File lib/rubygems/dependency_installer.rb, line 217
def add_found_dependencies to_do, dependency_list
  seen = {}
  dependencies = Hash.new { |h, name| h[name] = Gem::Dependency.new name }

  until to_do.empty? do
    spec = to_do.shift

    # HACK why is spec nil?
    next if spec.nil? or seen[spec.name]
    seen[spec.name] = true

    deps = spec.runtime_dependencies

    if @development
      if @dev_shallow
        if @toplevel_specs.include? spec.full_name
          deps |= spec.development_dependencies
        end
      else
        deps |= spec.development_dependencies
      end
    end

    deps.each do |dep|
      dependencies[dep.name] = dependencies[dep.name].merge dep

      if @minimal_deps
        next if Gem::Specification.any? do |installed_spec|
                  dep.name == installed_spec.name and
                    dep.requirement.satisfied_by? installed_spec.version
                end
      end

      results = find_gems_with_sources(dep)

      results.sorted.each do |t|
        to_do.push t.spec
      end

      results.remove_installed! dep

      @available << results
      results.inject_into_list dependency_list
    end
  end

  dependency_list.remove_specs_unsatisfied_by dependencies
end
consider_local?() click to toggle source

Indicated, based on the requested domain, if local gems should be considered.

# File lib/rubygems/dependency_installer.rb, line 123
def consider_local?
  @domain == :both or @domain == :local
end
consider_remote?() click to toggle source

Indicated, based on the requested domain, if remote gems should be considered.

# File lib/rubygems/dependency_installer.rb, line 131
def consider_remote?
  @domain == :both or @domain == :remote
end
find_gems_with_sources(dep) click to toggle source

Returns a list of pairs of gemspecs and source_uris that match Gem::Dependency dep from both local (Dir.pwd) and remote (Gem.sources) sources. Gems are sorted with newer gems preferred over older gems, and local gems preferred over remote gems.

# File lib/rubygems/dependency_installer.rb, line 141
def find_gems_with_sources(dep)
  set = Gem::AvailableSet.new

  if consider_local?
    sl = Gem::Source::Local.new

    if spec = sl.find_gem(dep.name)
      if dep.matches_spec? spec
        set.add spec, sl
      end
    end
  end

  if consider_remote?
    begin
      found, errors = Gem::SpecFetcher.fetcher.spec_for_dependency dep

      if @errors
        @errors += errors
      else
        @errors = errors
      end

      set << found

    rescue Gem::RemoteFetcher::FetchError => e
      # FIX if there is a problem talking to the network, we either need to always tell
      # the user (no really_verbose) or fail hard, not silently tell them that we just
      # couldn't find their requested gem.
      if Gem.configuration.really_verbose then
        say "Error fetching remote data:\t\t#{e.message}"
        say "Falling back to local-only install"
      end
      @domain = :local
    end
  end

  set
end
find_spec_by_name_and_version(gem_name, version = Gem::Requirement.default, prerelease = false) click to toggle source

Finds a spec and the source_uri it came from for gem gem_name and version. Returns an Array of specs and sources required for installation of the gem.

# File lib/rubygems/dependency_installer.rb, line 271
def find_spec_by_name_and_version(gem_name,
                                  version = Gem::Requirement.default,
                                  prerelease = false)

  set = Gem::AvailableSet.new

  if consider_local?
    if gem_name =~ /\.gem$/ and File.file? gem_name then
      src = Gem::Source::SpecificFile.new(gem_name)
      set.add src.spec, src
    elsif gem_name =~ /\.gem$/ then
      Dir[gem_name].each do |name|
        begin
          src = Gem::Source::SpecificFile.new name
          set.add src.spec, src
        rescue Gem::Package::FormatError
        end
      end
    else
      local = Gem::Source::Local.new

      if s = local.find_gem(gem_name, version)
        set.add s, local
      end
    end
  end

  if set.empty?
    dep = Gem::Dependency.new gem_name, version
    # HACK Dependency objects should be immutable
    dep.prerelease = true if prerelease

    set = find_gems_with_sources(dep)
    set.match_platform!
  end

  if set.empty?
    raise Gem::SpecificGemNotFoundException.new(gem_name, version, @errors)
  end

  @available = set
end
gather_dependencies() click to toggle source

Gathers all dependencies necessary for the installation from local and remote sources unless the ignore_dependencies was given.

# File lib/rubygems/dependency_installer.rb, line 185
def gather_dependencies
  specs = @available.all_specs

  # these gems were listed by the user, always install them
  keep_names = specs.map { |spec| spec.full_name }

  if @dev_shallow
    @toplevel_specs = keep_names
  end

  dependency_list = Gem::DependencyList.new @development
  dependency_list.add(*specs)
  to_do = specs.dup
  add_found_dependencies to_do, dependency_list unless @ignore_dependencies

  # REFACTOR maybe abstract away using Gem::Specification.include? so
  # that this isn't dependent only on the currently installed gems
  dependency_list.specs.reject! { |spec|
    not keep_names.include?(spec.full_name) and
    Gem::Specification.include?(spec)
  }

  unless dependency_list.ok? or @ignore_dependencies or @force then
    reason = dependency_list.why_not_ok?.map { |k,v|
      "#{k} requires #{v.join(", ")}"
    }.join("; ")
    raise Gem::DependencyError, "Unable to resolve dependencies: #{reason}"
  end

  @gems_to_install = dependency_list.dependency_order.reverse
end
in_background(what) { || ... } click to toggle source
# File lib/rubygems/dependency_installer.rb, line 396
def in_background what
  fork_happened = false
  if @build_docs_in_background and Process.respond_to?(:fork)
    begin
      Process.fork do
        yield
      end
      fork_happened = true
      say "#{what} in a background process."
    rescue NotImplementedError
    end
  end
  yield unless fork_happened
end
install(dep_or_name, version = Gem::Requirement.default) click to toggle source

Installs the gem dep_or_name and all its dependencies. Returns an Array of installed gem specifications.

If the :prerelease option is set and there is a prerelease for dep_or_name the prerelease version will be installed.

Unless explicitly specified as a prerelease dependency, prerelease gems that dep_or_name depend on will not be installed.

If c-1.a depends on b-1 and a-1.a and there is a gem b-1.a available then c-1.a, b-1 and a-1.a will be installed. b-1.a will need to be installed separately.

# File lib/rubygems/dependency_installer.rb, line 328
def install dep_or_name, version = Gem::Requirement.default
  available_set_for dep_or_name, version

  @installed_gems = []

  gather_dependencies

  # REFACTOR is the last gem always the one that the user requested?
  # This code assumes that but is that actually validated by the code?

  last = @gems_to_install.size - 1
  @gems_to_install.each_with_index do |spec, index|
    # REFACTOR more current spec set hardcoding, should be abstracted?
    next if Gem::Specification.include?(spec) and index != last

    # TODO: make this sorta_verbose so other users can benefit from it
    say "Installing gem #{spec.full_name}" if Gem.configuration.really_verbose

    source = @available.source_for spec

    begin
      # REFACTOR make the fetcher to use configurable
      local_gem_path = source.download spec, @cache_dir
    rescue Gem::RemoteFetcher::FetchError
      # TODO I doubt all fetch errors are recoverable, we should at least
      # report the errors probably.
      next if @force
      raise
    end

    if @development
      if @dev_shallow
        is_dev = @toplevel_specs.include? spec.full_name
      else
        is_dev = true
      end
    end

    inst = Gem::Installer.new local_gem_path,
                              :bin_dir             => @bin_dir,
                              :development         => is_dev,
                              :env_shebang         => @env_shebang,
                              :force               => @force,
                              :format_executable   => @format_executable,
                              :ignore_dependencies => @ignore_dependencies,
                              :install_dir         => @install_dir,
                              :security_policy     => @security_policy,
                              :user_install        => @user_install,
                              :wrappers            => @wrappers,
                              :build_args          => @build_args

    spec = inst.install

    @installed_gems << spec
  end

  # Since this is currently only called for docs, we can be lazy and just say
  # it's documentation. Ideally the hook adder could decide whether to be in
  # the background or not, and what to call it.
  in_background "Installing documentation" do
    Gem.done_installing_hooks.each do |hook|
      hook.call self, @installed_gems
    end
  end unless Gem.done_installing_hooks.empty?

  @installed_gems
end


class Gem::DependencyList - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyList

Gem::DependencyList is used for installing and uninstalling gems in the correct order to avoid conflicts.

In Files

  • lib/rubygems/dependency_list.rb

Parent

Object

Included Modules

  • Enumerable
  • TSort

Attributes

development[RW]

Allows enabling/disabling use of development dependencies

specs[R]

Public Class Methods

from_specs() click to toggle source

Creates a DependencyList from the current specs.

# File lib/rubygems/dependency_list.rb, line 32
def self.from_specs
  list = new
  list.add(*Gem::Specification.to_a)
  list
end
new(development = false) click to toggle source

Creates a new DependencyList. If development is true, development dependencies will be included.

# File lib/rubygems/dependency_list.rb, line 42
def initialize development = false
  @specs = []

  @development = development
end

Public Instance Methods

add(*gemspecs) click to toggle source

Adds gemspecs to the dependency list.

# File lib/rubygems/dependency_list.rb, line 51
def add(*gemspecs)
  @specs.concat gemspecs
end
clear() click to toggle source
# File lib/rubygems/dependency_list.rb, line 55
def clear
  @specs.clear
end
dependency_order() click to toggle source

Return a list of the gem specifications in the dependency list, sorted in order so that no gemspec in the list depends on a gemspec earlier in the list.

This is useful when removing gems from a set of installed gems. By removing them in the returned order, you don't get into as many dependency issues.

If there are circular dependencies (yuck!), then gems will be returned in order until only the circular dependents and anything they reference are left. Then arbitrary gemspecs will be returned until the circular dependency is broken, after which gems will be returned in dependency order again.

# File lib/rubygems/dependency_list.rb, line 74
def dependency_order
  sorted = strongly_connected_components.flatten

  result = []
  seen = {}

  sorted.each do |spec|
    if index = seen[spec.name] then
      if result[index].version < spec.version then
        result[index] = spec
      end
    else
      seen[spec.name] = result.length
      result << spec
    end
  end

  result.reverse
end
each(&block) click to toggle source

Iterator over #dependency_order

# File lib/rubygems/dependency_list.rb, line 97
def each(&block)
  dependency_order.each(&block)
end
find_name(full_name) click to toggle source
# File lib/rubygems/dependency_list.rb, line 101
def find_name(full_name)
  @specs.find { |spec| spec.full_name == full_name }
end
ok?() click to toggle source

Are all the dependencies in the list satisfied?

# File lib/rubygems/dependency_list.rb, line 112
def ok?
  why_not_ok?(:quick).empty?
end
ok_to_remove?(full_name, check_dev=true) click to toggle source

Is is ok to remove a gemspec from the dependency list?

If removing the gemspec creates breaks a currently ok dependency, then it is NOT ok to remove the gemspec.

# File lib/rubygems/dependency_list.rb, line 141
def ok_to_remove?(full_name, check_dev=true)
  gem_to_remove = find_name full_name

  siblings = @specs.find_all { |s|
    s.name == gem_to_remove.name &&
      s.full_name != gem_to_remove.full_name
  }

  deps = []

  @specs.each do |spec|
    check = check_dev ? spec.dependencies : spec.runtime_dependencies

    check.each do |dep|
      deps << dep if gem_to_remove.satisfies_requirement?(dep)
    end
  end

  deps.all? { |dep|
    siblings.any? { |s|
      s.satisfies_requirement? dep
    }
  }
end
remove_by_name(full_name) click to toggle source

Removes the gemspec matching full_name from the dependency list

# File lib/rubygems/dependency_list.rb, line 181
def remove_by_name(full_name)
  @specs.delete_if { |spec| spec.full_name == full_name }
end
remove_specs_unsatisfied_by(dependencies) click to toggle source

Remove everything in the DependencyList that matches but doesn't satisfy items in dependencies (a hash of gem names to arrays of dependencies).

# File lib/rubygems/dependency_list.rb, line 171
def remove_specs_unsatisfied_by dependencies
  specs.reject! { |spec|
    dep = dependencies[spec.name]
    dep and not dep.requirement.satisfied_by? spec.version
  }
end
spec_predecessors() click to toggle source

Return a hash of predecessors. result[spec] is an Array of gemspecs that have a dependency satisfied by the named gemspec.

# File lib/rubygems/dependency_list.rb, line 189
def spec_predecessors
  result = Hash.new { |h,k| h[k] = [] }

  specs = @specs.sort.reverse

  specs.each do |spec|
    specs.each do |other|
      next if spec == other

      other.dependencies.each do |dep|
        if spec.satisfies_requirement? dep then
          result[spec] << other
        end
      end
    end
  end

  result
end
tsort_each_child(node) { |spec| ... } click to toggle source
# File lib/rubygems/dependency_list.rb, line 213
def tsort_each_child(node)
  specs = @specs.sort.reverse

  dependencies = node.runtime_dependencies
  dependencies.push(*node.development_dependencies) if @development

  dependencies.each do |dep|
    specs.each do |spec|
      if spec.satisfies_requirement? dep then
        begin
          yield spec
        rescue TSort::Cyclic
          # do nothing
        end
        break
      end
    end
  end
end
tsort_each_node(&block) click to toggle source
# File lib/rubygems/dependency_list.rb, line 209
def tsort_each_node(&block)
  @specs.each(&block)
end
why_not_ok?(quick = false) click to toggle source
# File lib/rubygems/dependency_list.rb, line 116
def why_not_ok? quick = false
  unsatisfied = Hash.new { |h,k| h[k] = [] }
  each do |spec|
    spec.runtime_dependencies.each do |dep|
      inst = Gem::Specification.any? { |installed_spec|
        dep.name == installed_spec.name and
          dep.requirement.satisfied_by? installed_spec.version
      }

      unless inst or @specs.find { |s| s.satisfies_requirement? dep } then
        unsatisfied[spec.name] << dep
        return unsatisfied if quick
      end
    end
  end

  unsatisfied
end


class Gem::DependencyRemovalException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyRemovalException

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::DependencyResolutionError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyResolutionError

Raised when a DependencyConflict reaches the toplevel. Indicates which dependencies were incompatible.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Gem::Exception

Attributes

conflict[R]

Public Class Methods

new(conflict) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 14
def initialize(conflict)
  @conflict = conflict
  a, b = conflicting_dependencies

  super "unable to resolve conflicting dependencies '#{a}' and '#{b}'"
end

Public Instance Methods

conflicting_dependencies() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 23
def conflicting_dependencies
  @conflict.conflicting_dependencies
end


class Gem::DependencyResolver - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyResolver

Given a set of Gem::Dependency objects as needed and a way to query the set of available specs via set, calculates a set of ActivationRequest objects which indicate all the specs that should be activated to meet the all the requirements.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Object

Attributes

conflicts[R]

Contains all the conflicts encountered while doing resolution

Public Class Methods

for_current_gems(needed) click to toggle source

Provide a DependencyResolver that queries only against the already installed gems.

# File lib/rubygems/dependency_resolver.rb, line 270
def self.for_current_gems(needed)
  new needed, CurrentSet.new
end
new(needed, set=IndexSet.new) click to toggle source

Create DependencyResolver object which will resolve the tree starting with needed Depedency objects.

set is an object that provides where to look for specifications to satisify the Dependencies. This defaults to IndexSet, which will query rubygems.org.

# File lib/rubygems/dependency_resolver.rb, line 260
def initialize(needed, set=IndexSet.new)
  @set = set || IndexSet.new # Allow nil to mean IndexSet
  @needed = needed

  @conflicts = nil
end

Public Instance Methods

requests(s, act) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 437
def requests(s, act)
  reqs = []
  s.dependencies.each do |d|
    next unless d.type == :runtime
    reqs << DependencyRequest.new(d, act)
  end

  @set.prefetch(reqs)

  reqs
end
resolve() click to toggle source

Proceed with resolution! Returns an array of ActivationRequest objects.

# File lib/rubygems/dependency_resolver.rb, line 281
def resolve
  @conflicts = []

  needed = @needed.map { |n| DependencyRequest.new(n, nil) }

  res = resolve_for needed, []

  if res.kind_of? DependencyConflict
    raise DependencyResolutionError.new(res)
  end

  res
end
resolve_for(needed, specs) click to toggle source

The meat of the algorithm. Given needed DependencyRequest objects and specs being a list to ActivationRequest, calculate a new list of ActivationRequest objects.

# File lib/rubygems/dependency_resolver.rb, line 453
def resolve_for(needed, specs)
  until needed.empty?
    dep = needed.shift

    # If there is already a spec activated for the requested name...
    if existing = specs.find { |s| dep.name == s.name }

      # then we're done since this new dep matches the
      # existing spec.
      next if dep.matches_spec? existing

      # There is a conflict! We return the conflict
      # object which will be seen by the caller and be
      # handled at the right level.

      # If the existing activation indicates that there
      # are other possibles for it, then issue the conflict
      # on the dep for the activation itself. Otherwise, issue
      # it on the requester's request itself.
      #
      if existing.others_possible?
        conflict = DependencyConflict.new(dep, existing)
      else
        depreq = existing.request.requester.request
        conflict = DependencyConflict.new(depreq, existing, dep)
      end
      @conflicts << conflict

      return conflict
    end

    # Get a list of all specs that satisfy dep
    possible = @set.find_all(dep)

    case possible.size
    when 0
      # If there are none, then our work here is done.
      raise UnsatisfiableDepedencyError.new(dep)
    when 1
      # If there is one, then we just add it to specs
      # and process the specs dependencies by adding
      # them to needed.

      spec = possible.first
      act =  ActivationRequest.new(spec, dep, false)

      specs << act

      # Put the deps for at the beginning of needed
      # rather than the end to match the depth first
      # searching done by the multiple case code below.
      #
      # This keeps the error messages consistent.
      needed = requests(spec, act) + needed
    else
      # There are multiple specs for this dep. This is
      # the case that this class is built to handle.

      # Sort them so that we try the highest versions
      # first.
      possible = possible.sort_by { |s| s.version }

      # We track the conflicts seen so that we can report them
      # to help the user figure out how to fix the situation.
      conflicts = []

      # To figure out which to pick, we keep resolving
      # given each one being activated and if there isn't
      # a conflict, we know we've found a full set.
      #
      # We use an until loop rather than #reverse_each
      # to keep the stack short since we're using a recursive
      # algorithm.
      #
      until possible.empty?
        s = possible.pop

        # Recursively call #resolve_for with this spec
        # and add it's dependencies into the picture...

        act = ActivationRequest.new(s, dep)

        try = requests(s, act) + needed

        res = resolve_for(try, specs + [act])

        # While trying to resolve these dependencies, there may
        # be a conflict!

        if res.kind_of? DependencyConflict
          # The conflict might be created not by this invocation
          # but rather one up the stack, so if we can't attempt
          # to resolve this conflict (conflict isn't with the spec +s+)
          # then just return it so the caller can try to sort it out.
          return res unless res.for_spec? s

          # Otherwise, this is a conflict that we can attempt to fix
          conflicts << [s, res]

          # Optimization:
          #
          # Because the conflict indicates the dependency that trigger
          # it, we can prune possible based on this new information.
          #
          # This cuts down on the number of iterations needed.
          possible.delete_if { |x| !res.dependency.matches_spec? x }
        else
          # No conflict, return the specs
          return res
        end
      end

      # We tried all possibles and nothing worked, so we let the user
      # know and include as much information about the problem since
      # the user is going to have to take action to fix this.
      raise ImpossibleDependenciesError.new(dep, conflicts)
    end
  end

  specs
end


class Gem::DependencyResolver::APISet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyResolver::APISet

The global rubygems pool, available via the rubygems.org API. Returns instances of APISpecification.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Object

Public Class Methods

new() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 102
def initialize
  @data = Hash.new { |h,k| h[k] = [] }
  @dep_uri = URI 'https://rubygems.org/api/v1/dependencies'
end

Public Instance Methods

find_all(req) click to toggle source

Return an array of APISpecification objects matching DependencyRequest req.

# File lib/rubygems/dependency_resolver.rb, line 127
def find_all(req)
  res = []

  versions(req.name).each do |ver|
    if req.dependency.match? req.name, ver[:number]
      res << APISpecification.new(self, ver)
    end
  end

  res
end
prefetch(reqs) click to toggle source

A hint run by the resolver to allow the Set to fetch data for DependencyRequests reqs.

# File lib/rubygems/dependency_resolver.rb, line 142
def prefetch(reqs)
  names = reqs.map { |r| r.dependency.name }
  needed = names.find_all { |d| !@data.key?(d) }

  return if needed.empty?

  uri = @dep_uri + "?gems=#{needed.sort.join ','}"
  str = Gem::RemoteFetcher.fetcher.fetch_path uri

  Marshal.load(str).each do |ver|
    @data[ver[:name]] << ver
  end
end
versions(name) click to toggle source

Return data for all versions of the gem name.

# File lib/rubygems/dependency_resolver.rb, line 109
def versions(name)
  if @data.key?(name)
    return @data[name]
  end

  uri = @dep_uri + "?gems=#{name}"
  str = Gem::RemoteFetcher.fetcher.fetch_path uri

  Marshal.load(str).each do |ver|
    @data[ver[:name]] << ver
  end

  @data[name]
end


class Gem::DependencyResolver::APISpecification - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyResolver::APISpecification

Represents a specification retrieved via the rubygems.org API. This is used to avoid having to load the full Specification object when all we need is the name, version, and dependencies.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Object

Attributes

dependencies[R]
name[R]
version[R]

Public Class Methods

new(set, api_data) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 74
def initialize(set, api_data)
  @set = set
  @name = api_data[:name]
  @version = Gem::Version.new api_data[:number]
  @dependencies = api_data[:dependencies].map do |name, ver|
    Gem::Dependency.new name, ver.split(/\s*,\s*/)
  end
end

Public Instance Methods

full_name() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 93
def full_name
  "#{@name}-#{@version}"
end


class Gem::DependencyResolver::ActivationRequest - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyResolver::ActivationRequest

Specifies a Specification object that should be activated. Also contains a dependency that was used to introduce this activation.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Object

Attributes

request[R]
spec[R]

Public Class Methods

new(spec, req, others_possible=true) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 364
def initialize(spec, req, others_possible=true)
  @spec = spec
  @request = req
  @others_possible = others_possible
end

Public Instance Methods

==(other) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 414
def ==(other)
  case other
  when Gem::Specification
    @spec == other
  when ActivationRequest
    @spec == other.spec && @request == other.request
  else
    false
  end
end
download(path) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 402
def download(path)
  if @spec.respond_to? :source
    source = @spec.source
  else
    source = Gem.sources.first
  end

  Gem.ensure_gem_subdirectories path

  source.download full_spec, path
end
full_name() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 390
def full_name
  @spec.full_name
end
full_spec() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 398
def full_spec
  Gem::Specification === @spec ? @spec : @spec.spec
end
installed?() click to toggle source

Indicates if the requested gem has already been installed.

# File lib/rubygems/dependency_resolver.rb, line 428
def installed?
  this_spec = full_spec

  Gem::Specification.any? do |s|
    s == this_spec
  end
end
name() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 386
def name
  @spec.name
end
others_possible?() click to toggle source

Indicate if this activation is one of a set of possible requests for the same Dependency request.

# File lib/rubygems/dependency_resolver.rb, line 375
def others_possible?
  @others_possible
end
parent() click to toggle source

Return the ActivationRequest that contained the dependency that we were activated for.

# File lib/rubygems/dependency_resolver.rb, line 382
def parent
  @request.requester
end
version() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 394
def version
  @spec.version
end


class Gem::DependencyResolver::CurrentSet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyResolver::CurrentSet

A set which represents the installed gems. Respects all the normal settings that control where to look for installed gems.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Object

Public Instance Methods

find_all(req) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 245
def find_all(req)
  req.dependency.matching_specs
end
prefetch(gems) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 249
def prefetch(gems)
end


class Gem::DependencyResolver::DependencyConflict - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyResolver::DependencyConflict

Used internally to indicate that a dependency conflicted with a spec that would be activated.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Object

Attributes

activated[R]
dependency[R]

Public Class Methods

new(dependency, activated, failed_dep=dependency) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 299
def initialize(dependency, activated, failed_dep=dependency)
  @dependency = dependency
  @activated = activated
  @failed_dep = failed_dep
end

Public Instance Methods

conflicting_dependencies() click to toggle source

Return the 2 dependency objects that conflicted

# File lib/rubygems/dependency_resolver.rb, line 319
def conflicting_dependencies
  [@failed_dep.dependency, @activated.request.dependency]
end
for_spec?(spec) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 313
def for_spec?(spec)
  @dependency.name == spec.name
end
requester() click to toggle source

Return the Specification that listed the dependency

# File lib/rubygems/dependency_resolver.rb, line 309
def requester
  @failed_dep.requester
end


class Gem::DependencyResolver::DependencyRequest - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyResolver::DependencyRequest

Used Internally. Wraps a Depedency object to also track which spec contained the Dependency.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Object

Attributes

dependency[R]
requester[R]

Public Class Methods

new(dep, act) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 328
def initialize(dep, act)
  @dependency = dep
  @requester = act
end

Public Instance Methods

==(other) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 347
def ==(other)
  case other
  when Dependency
    @dependency == other
  when DependencyRequest
    @dependency == other.dependency && @requester == other.requester
  else
    false
  end
end
matches_spec?(spec) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 339
def matches_spec?(spec)
  @dependency.matches_spec? spec
end
name() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 335
def name
  @dependency.name
end
to_s() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 343
def to_s
  @dependency.to_s
end


class Gem::DependencyResolver::IndexSet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyResolver::IndexSet

The global rubygems pool represented via the traditional source index.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Object

Public Class Methods

new() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 192
def initialize
  @f = Gem::SpecFetcher.fetcher

  @all = Hash.new { |h,k| h[k] = [] }

  list, _ = @f.available_specs(:released)
  list.each do |uri, specs|
    specs.each do |n|
      @all[n.name] << [uri, n]
    end
  end

  @specs = {}
end

Public Instance Methods

find_all(req) click to toggle source

Return an array of IndexSpecification objects matching DependencyRequest req.

# File lib/rubygems/dependency_resolver.rb, line 210
def find_all(req)
  res = []

  name = req.dependency.name

  @all[name].each do |uri, n|
    if req.dependency.match? n
      res << IndexSpecification.new(self, n.name, n.version,
                                    uri, n.platform)
    end
  end

  res
end
load_spec(name, ver, source) click to toggle source

Called from IndexSpecification to get a true Specification object.

# File lib/rubygems/dependency_resolver.rb, line 234
def load_spec(name, ver, source)
  key = "#{name}-#{ver}"
  @specs[key] ||= source.fetch_spec(Gem::NameTuple.new(name, ver))
end
prefetch(gems) click to toggle source

No prefetching needed since we load the whole index in initially.

# File lib/rubygems/dependency_resolver.rb, line 228
def prefetch(gems)
end


class Gem::DependencyResolver::IndexSpecification - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DependencyResolver::IndexSpecification

Represents a possible Specification object returned from IndexSet. Used to delay needed to download full Specification objects when only the name and version are needed.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Object

Attributes

name[R]
source[R]
version[R]

Public Class Methods

new(set, name, version, source, plat) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 163
def initialize(set, name, version, source, plat)
  @set = set
  @name = name
  @version = version
  @source = source
  @platform = plat

  @spec = nil
end

Public Instance Methods

dependencies() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 183
def dependencies
  spec.dependencies
end
full_name() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 175
def full_name
  "#{@name}-#{@version}"
end
spec() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 179
def spec
  @spec ||= @set.load_spec(@name, @version, @source)
end


module Gem::Deprecate - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::Deprecate

Provides a single method deprecate to be used to declare when something is going away.

class Legacy
  def self.klass_method
    # ...
  end

  def instance_method
    # ...
  end

  extend Gem::Deprecate
  deprecate :instance_method, "X.z", 2011, 4

  class << self
    extend Gem::Deprecate
    deprecate :klass_method, :none, 2011, 4
  end
end

In Files

  • lib/rubygems/deprecate.rb

Public Class Methods

deprecate(name, repl, year, month) click to toggle source

Simple deprecation method that deprecates name by wrapping it up in a dummy method. It warns on each call to the dummy method telling the user of repl (unless repl is :none) and the year/month that it is planned to go away.

# File lib/rubygems/deprecate.rb, line 49
def deprecate name, repl, year, month
  class_eval {
    old = "_deprecated_#{name}"
    alias_method old, name
    define_method name do |*args, &block| # TODO: really works on 1.8.7?
      klass = self.kind_of? Module
      target = klass ? "#{self}." : "#{self.class}#"
      msg = [ "NOTE: #{target}#{name} is deprecated",
        repl == :none ? " with no replacement" : "; use #{repl} instead",
        ". It will be removed on or after %4d-%02d-01." % [year, month],
        "\n#{target}#{name} called from #{Gem.location_of_caller.join(":")}",
      ]
      warn "#{msg.join}." unless Gem::Deprecate.skip
      send old, *args, &block
    end
  }
end
skip_during() { || ... } click to toggle source

Temporarily turn off warnings. Intended for tests only.

# File lib/rubygems/deprecate.rb, line 36
def skip_during
  Gem::Deprecate.skip, original = true, Gem::Deprecate.skip
  yield
ensure
  Gem::Deprecate.skip = original
end


class Gem::Doctor - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Doctor

Cleans up after a partially-failed uninstall or for an invalid Gem::Specification.

If a specification was removed by hand this will remove any remaining files.

If a corrupt specification was installed this will clean up warnings by removing the bogus specification.

In Files

  • lib/rubygems/doctor.rb

Parent

Object

Included Modules

  • Gem::UserInteraction

Public Class Methods

new(gem_repository, dry_run = false) click to toggle source

Creates a new Gem::Doctor that will clean up gem_repository. Only one gem repository may be cleaned at a time.

If dry_run is true no files or directories will be removed.

# File lib/rubygems/doctor.rb, line 40
def initialize gem_repository, dry_run = false
  @gem_repository = Pathname(gem_repository)
  @dry_run        = dry_run

  @installed_specs = nil
end

Public Instance Methods

doctor() click to toggle source

Cleans up uninstalled files and invalid gem specifications

# File lib/rubygems/doctor.rb, line 64
def doctor
  @orig_home = Gem.dir
  @orig_path = Gem.path

  say "Checking #{@gem_repository}"

  Gem.use_paths @gem_repository.to_s

  unless gem_repository? then
    say 'This directory does not appear to be a RubyGems repository, ' +
        'skipping'
    say
    return
  end

  doctor_children

  say
ensure
  Gem.use_paths @orig_home, *@orig_path
end
gem_repository?() click to toggle source

Are we doctoring a gem repository?

# File lib/rubygems/doctor.rb, line 57
def gem_repository?
  not installed_specs.empty?
end


class Gem::DocumentError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::DocumentError

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::EndOfYAMLException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::EndOfYAMLException

Potentially raised when a specification is validated.

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::ErrorReason - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::ErrorReason

FIX: does this need to exist? The subclass is the only other reference I can find.

In Files

  • lib/rubygems/errors.rb

Parent

Object


class Gem::Exception - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Exception

Base exception class for RubyGems. All exception raised by RubyGems are a subclass of this one.

In Files

  • lib/rubygems/exceptions.rb

Parent

RuntimeError

Attributes

source_exception[RW]


module Gem::Ext - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::Ext

Classes for building C extensions live here.

In Files

  • lib/rubygems/ext.rb


class Gem::Ext::Builder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Ext::Builder

In Files

  • lib/rubygems/ext/builder.rb

Parent

Object

Public Class Methods

class_name() click to toggle source
# File lib/rubygems/ext/builder.rb, line 9
def self.class_name
  name =~ /Ext::(.*)Builder/
  $1.downcase
end
make(dest_path, results) click to toggle source
# File lib/rubygems/ext/builder.rb, line 14
def self.make(dest_path, results)
  unless File.exist? 'Makefile' then
    raise Gem::InstallError, "Makefile not found:\n\n#{results.join "\n"}"
  end

  # try to find make program from Ruby configure arguments first
  RbConfig::CONFIG['configure_args'] =~ /with-make-prog\=(\w+)/
  make_program = $1 || ENV['MAKE'] || ENV['make']
  unless make_program then
    make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
  end

  destdir = '"DESTDIR=%s"' % ENV['DESTDIR'] if RUBY_VERSION > '2.0'

  ['', 'install'].each do |target|
    # Pass DESTDIR via command line to override what's in MAKEFLAGS
    cmd = [
      make_program,
      destdir,
      target
    ].join(' ').rstrip
    run(cmd, results, "make #{target}".rstrip)
  end
end
redirector() click to toggle source
# File lib/rubygems/ext/builder.rb, line 39
def self.redirector
  '2>&1'
end
run(command, results, command_name = nil) click to toggle source
# File lib/rubygems/ext/builder.rb, line 43
def self.run(command, results, command_name = nil)
  verbose = Gem.configuration.really_verbose

  begin
    # TODO use Process.spawn when ruby 1.8 support is dropped.
    rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], nil
    if verbose
      puts(command)
      system(command)
    else
      results << command
      results << %x#{command} #{redirector}`
    end
  ensure
    ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
  end

  unless $?.success? then
    results << "Building has failed. See above output for more information on the failure." if verbose
    raise Gem::InstallError, "#{command_name || class_name} failed:\n\n#{results.join "\n"}"
  end
end


class Gem::Ext::CmakeBuilder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Ext::CmakeBuilder

In Files

  • lib/rubygems/ext/cmake_builder.rb

Parent

Gem::Ext::Builder

Public Class Methods

build(extension, directory, dest_path, results) click to toggle source
# File lib/rubygems/ext/cmake_builder.rb, line 2
def self.build(extension, directory, dest_path, results)
  unless File.exist?('Makefile') then
    cmd = "cmake . -DCMAKE_INSTALL_PREFIX=#{dest_path}"
    cmd << " #{Gem::Command.build_args.join ' '}" unless Gem::Command.build_args.empty?

    run cmd, results
  end

  make dest_path, results

  results
end


class Gem::Ext::ConfigureBuilder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Ext::ConfigureBuilder

In Files

  • lib/rubygems/ext/configure_builder.rb

Parent

Gem::Ext::Builder

Public Class Methods

build(extension, directory, dest_path, results, args=[]) click to toggle source
# File lib/rubygems/ext/configure_builder.rb, line 11
def self.build(extension, directory, dest_path, results, args=[])
  unless File.exist?('Makefile') then
    cmd = "sh ./configure --prefix=#{dest_path}"
    cmd << " #{args.join ' '}" unless args.empty?

    run cmd, results
  end

  make dest_path, results

  results
end


class Gem::Ext::ExtConfBuilder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Ext::ExtConfBuilder

In Files

  • lib/rubygems/ext/ext_conf_builder.rb

Parent

Gem::Ext::Builder

Public Class Methods

build(extension, directory, dest_path, results, args=[]) click to toggle source
# File lib/rubygems/ext/ext_conf_builder.rb, line 15
def self.build(extension, directory, dest_path, results, args=[])
  tmp_dest = Dir.mktmpdir(".gem.", ".")

  t = nil
  Tempfile.open %wsiteconf .rb", "." do |siteconf|
    t = siteconf
    siteconf.puts "require 'rbconfig'"
    siteconf.puts "dest_path = #{(tmp_dest || dest_path).dump}"
    %w[sitearchdir sitelibdir].each do |dir|
      siteconf.puts "RbConfig::MAKEFILE_CONFIG['#{dir}'] = dest_path"
      siteconf.puts "RbConfig::CONFIG['#{dir}'] = dest_path"
    end

    siteconf.flush

    siteconf_path = File.expand_path siteconf.path

    rubyopt = ENV["RUBYOPT"]
    destdir = ENV["DESTDIR"]

    begin
      ENV["RUBYOPT"] = ["-r#{siteconf_path}", rubyopt].compact.join(' ')
      cmd = [Gem.ruby, File.basename(extension), *args].join ' '

      run cmd, results

      ENV["DESTDIR"] = nil
      ENV["RUBYOPT"] = rubyopt
      siteconf.unlink

      make dest_path, results

      if tmp_dest
        FileEntry.new(tmp_dest).traverse do |ent|
          destent = ent.class.new(dest_path, ent.rel)
          destent.exist? or File.rename(ent.path, destent.path)
        end
      end
    ensure
      ENV["RUBYOPT"] = rubyopt
      ENV["DESTDIR"] = destdir
    end
  end
  t.unlink if t and t.path

  results
ensure
  FileUtils.rm_rf tmp_dest if tmp_dest
end


class Gem::Ext::RakeBuilder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Ext::RakeBuilder

In Files

  • lib/rubygems/ext/rake_builder.rb

Parent

Gem::Ext::Builder

Public Class Methods

build(extension, directory, dest_path, results, args=[]) click to toggle source
# File lib/rubygems/ext/rake_builder.rb, line 12
def self.build(extension, directory, dest_path, results, args=[])
  if File.basename(extension) =~ /mkrf_conf/ then
    cmd = "#{Gem.ruby} #{File.basename extension}"
    cmd << " #{args.join " "}" unless args.empty?
    run cmd, results
  end

  # Deal with possible spaces in the path, e.g. C:/Program Files
  dest_path = '"' + dest_path.to_s + '"' if dest_path.to_s.include?(' ')

  rake = ENV['rake']

  rake ||= begin
             "\"#{Gem.ruby}\" -rubygems #{Gem.bin_path('rake', 'rake')}"
           rescue Gem::Exception
           end

  rake ||= Gem.default_exec_format % 'rake'

  cmd = "#{rake} RUBYARCHDIR=#{dest_path} RUBYLIBDIR=#{dest_path}" # ENV is frozen

  run cmd, results

  results
end


class Gem::FakeFetcher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::FakeFetcher

A fake Gem::RemoteFetcher for use in tests or to avoid real live HTTP requests when testing code that uses RubyGems.

Example:

@fetcher = Gem::FakeFetcher.new
@fetcher.data['http://gems.example.com/yaml'] = source_index.to_yaml
Gem::RemoteFetcher.fetcher = @fetcher

# invoke RubyGems code

paths = @fetcher.paths
assert_equal 'http://gems.example.com/yaml', paths.shift
assert paths.empty?, paths.join(', ')

See RubyGems' tests for more examples of FakeFetcher.

In Files

  • lib/rubygems/test_utilities.rb

Parent

Object

Attributes

api_endpoints[R]
data[R]
last_request[R]
paths[RW]

Public Class Methods

new() click to toggle source
# File lib/rubygems/test_utilities.rb, line 30
def initialize
  @data = {}
  @paths = []
  @api_endpoints = {}
end

Public Instance Methods

api_endpoint(uri) click to toggle source
# File lib/rubygems/test_utilities.rb, line 36
def api_endpoint(uri)
  @api_endpoints[uri] || uri
end
cache_update_path(uri, path = nil, update = true) click to toggle source
# File lib/rubygems/test_utilities.rb, line 71
def cache_update_path uri, path = nil, update = true
  if data = fetch_path(uri)
    open(path, 'wb') { |io| io.write data } if path and update
    data
  else
    Gem.read_binary(path) if path
  end
end
download(spec, source_uri, install_dir = Gem.dir) click to toggle source
# File lib/rubygems/test_utilities.rb, line 119
def download spec, source_uri, install_dir = Gem.dir
  name = File.basename spec.cache_file
  path = if Dir.pwd == install_dir then # see fetch_command
           install_dir
         else
           File.join install_dir, "cache"
         end

  path = File.join path, name

  if source_uri =~ /^http/ then
    File.open(path, "wb") do |f|
      f.write fetch_path(File.join(source_uri, "gems", name))
    end
  else
    FileUtils.cp source_uri, path
  end

  path
end
download_to_cache(dependency) click to toggle source
# File lib/rubygems/test_utilities.rb, line 140
def download_to_cache dependency
  found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dependency

  return if found.empty?

  spec, source = found.first

  download spec, source.uri.to_s
end
fetch_path(path, mtime = nil, head = false) click to toggle source
# File lib/rubygems/test_utilities.rb, line 57
def fetch_path path, mtime = nil, head = false
  data = find_data(path)

  if data.respond_to?(:call) then
    data.call
  else
    if path.to_s =~ /gz$/ and not data.nil? and not data.empty? then
      data = Gem.gunzip data
    end

    data
  end
end
fetch_size(path) click to toggle source
# File lib/rubygems/test_utilities.rb, line 104
def fetch_size(path)
  path = path.to_s
  @paths << path

  raise ArgumentError, 'need full URI' unless path =~ %r^http://'

  unless @data.key? path then
    raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
  end

  data = @data[path]

  data.respond_to?(:call) ? data.call : data.length
end
find_data(path) click to toggle source
# File lib/rubygems/test_utilities.rb, line 40
def find_data(path)
  if URI === path and "URI::#{path.scheme.upcase}" != path.class.name then
    raise ArgumentError,
      "mismatch for scheme #{path.scheme} and class #{path.class}"
  end

  path = path.to_s
  @paths << path
  raise ArgumentError, 'need full URI' unless path =~ %r^https?://'

  unless @data.key? path then
    raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
  end

  @data[path]
end
open_uri_or_path(path) click to toggle source

Thanks, FakeWeb!

# File lib/rubygems/test_utilities.rb, line 81
def open_uri_or_path(path)
  data = find_data(path)
  body, code, msg = data

  response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
  response.instance_variable_set(:@body, body)
  response.instance_variable_set(:@read, true)
  response
end
request(uri, request_class, last_modified = nil) { |last_request| ... } click to toggle source
# File lib/rubygems/test_utilities.rb, line 91
def request(uri, request_class, last_modified = nil)
  data = find_data(uri)
  body, code, msg = data

  @last_request = request_class.new uri.request_uri
  yield @last_request if block_given?

  response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
  response.instance_variable_set(:@body, body)
  response.instance_variable_set(:@read, true)
  response
end


class Gem::FilePermissionError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::FilePermissionError

Signals that a file permission error is preventing the user from operating on the given directory.

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception

Attributes

directory[R]

Public Class Methods

new(directory) click to toggle source
# File lib/rubygems/exceptions.rb, line 40
def initialize directory
  @directory = directory

  super "You don't have write permissions for the #{directory} directory."
end


class Gem::FormatException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::FormatException

Used to raise parsing and loading errors

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception

Attributes

file_path[RW]


class Gem::GemNotFoundException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::GemNotFoundException

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::GemNotInHomeException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::GemNotInHomeException

Raised when attempting to uninstall a gem that isn't in GEM_HOME.

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception

Attributes

spec[RW]


class Gem::GemRunner - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::GemRunner

Run an instance of the gem program.

Gem::GemRunner is only intended for internal use by RubyGems itself. It does not form any public API and may change at any time for any reason.

If you would like to duplicate functionality of `gem` commands, use the classes they call directly.

In Files

  • lib/rubygems/gem_runner.rb

Parent

Object

Public Class Methods

new(options={}) click to toggle source
# File lib/rubygems/gem_runner.rb, line 27
def initialize(options={})
  # TODO: nuke these options
  @command_manager_class = options[:command_manager] || Gem::CommandManager
  @config_file_class = options[:config_file] || Gem::ConfigFile
end

Public Instance Methods

run(args) click to toggle source

Run the gem command with the following arguments.

# File lib/rubygems/gem_runner.rb, line 36
def run(args)
  if args.include?('--')
    # We need to preserve the original ARGV to use for passing gem options
    # to source gems.  If there is a -- in the line, strip all options after
    # it...its for the source building process.
    # TODO use slice!
    build_args = args[args.index("--") + 1...args.length]
    args = args[0...args.index("--")]
  end

  do_configuration args
  cmd = @command_manager_class.instance

  cmd.command_names.each do |command_name|
    config_args = Gem.configuration[command_name]
    config_args = case config_args
                  when String
                    config_args.split ' '
                  else
                    Array(config_args)
                  end
    Gem::Command.add_specific_extra_args command_name, config_args
  end

  cmd.run Gem.configuration.args, build_args
end


module Gem::GemcutterUtilities - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::GemcutterUtilities

In Files

  • lib/rubygems/gemcutter_utilities.rb

Attributes

host[W]

Public Instance Methods

add_key_option() click to toggle source

Add the –key option

# File lib/rubygems/gemcutter_utilities.rb, line 12
def add_key_option
  add_option('-k', '--key KEYNAME', Symbol,
             'Use the given API key',
             'from ~/.gem/credentials') do |value,options|
    options[:key] = value
  end
end
api_key() click to toggle source
# File lib/rubygems/gemcutter_utilities.rb, line 20
def api_key
  if options[:key] then
    verify_api_key options[:key]
  elsif Gem.configuration.api_keys.key?(host)
    Gem.configuration.api_keys[host]
  else
    Gem.configuration.rubygems_api_key
  end
end
host() click to toggle source
# File lib/rubygems/gemcutter_utilities.rb, line 60
def host
  configured_host = Gem.host unless
    Gem.configuration.disable_default_gem_server

  @host ||=
    begin
      env_rubygems_host = ENV['RUBYGEMS_HOST']
      env_rubygems_host = nil if
        env_rubygems_host and env_rubygems_host.empty?

      env_rubygems_host|| configured_host
    end
end
rubygems_api_request(method, path, host = nil, &block) click to toggle source
# File lib/rubygems/gemcutter_utilities.rb, line 74
def rubygems_api_request(method, path, host = nil, &block)
  require 'net/http'

  self.host = host if host
  unless self.host
    alert_error "You must specify a gem server"
    terminate_interaction 1 # TODO: question this
  end

  uri = URI.parse "#{self.host}/#{path}"

  request_method = Net::HTTP.const_get method.to_s.capitalize

  Gem::RemoteFetcher.fetcher.request(uri, request_method, &block)
end
sign_in(sign_in_host = nil) click to toggle source
# File lib/rubygems/gemcutter_utilities.rb, line 30
def sign_in sign_in_host = nil
  sign_in_host ||= self.host
  return if Gem.configuration.rubygems_api_key

  pretty_host = if Gem::DEFAULT_HOST == sign_in_host then
                  'RubyGems.org'
                else
                  sign_in_host
                end

  say "Enter your #{pretty_host} credentials."
  say "Don't have an account yet? " +
      "Create one at #{sign_in_host}/sign_up"

  email    =              ask "   Email: "
  password = ask_for_password "Password: "
  say "\n"

  response = rubygems_api_request(:get, "api/v1/api_key",
                                  sign_in_host) do |request|
    request.basic_auth email, password
  end

  with_response response do |resp|
    say "Signed in."
    Gem.configuration.rubygems_api_key = resp.body
  end
end
verify_api_key(key) click to toggle source
# File lib/rubygems/gemcutter_utilities.rb, line 107
def verify_api_key(key)
  if Gem.configuration.api_keys.key? key then
    Gem.configuration.api_keys[key]
  else
    alert_error "No such API key. Please add it to your configuration (done automatically on initial `gem push`)."
    terminate_interaction 1 # TODO: question this
  end
end
with_response(resp, error_prefix = nil) { |resp| ... } click to toggle source
# File lib/rubygems/gemcutter_utilities.rb, line 90
def with_response resp, error_prefix = nil
  case resp
  when Net::HTTPSuccess then
    if block_given? then
      yield resp
    else
      say resp.body
    end
  else
    message = resp.body
    message = "#{error_prefix}: #{message}" if error_prefix

    say message
    terminate_interaction 1 # TODO: question this
  end
end


class Gem::ImpossibleDependenciesError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::ImpossibleDependenciesError

Raised when dependencies conflict and create the inability to find a valid possible spec for a request.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Gem::Exception

Attributes

conflicts[R]

Public Class Methods

new(request, conflicts) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 45
def initialize(request, conflicts)
  s = conflicts.size == 1 ? "" : "s"
  super "detected #{conflicts.size} conflict#{s} with dependency '#{request.dependency}'"
  @request = request
  @conflicts = conflicts
end

Public Instance Methods

dependency() click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 52
def dependency
  @request.dependency
end


class Gem::Indexer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Indexer

Top level class for building the gem repository index.

In Files

  • lib/rubygems/indexer.rb

Parent

Object

Included Modules

  • Gem::UserInteraction

Attributes

build_modern[RW]

Build indexes for RubyGems 1.2.0 and newer when true

dest_directory[R]

Index install location

dest_latest_specs_index[R]

Latest specs index install location

dest_prerelease_specs_index[R]

Prerelease specs index install location

dest_specs_index[R]

Specs index install location

directory[R]

Index build directory

Public Class Methods

new(directory, options = {}) click to toggle source

Create an indexer that will index the gems in directory.

# File lib/rubygems/indexer.rb, line 51
def initialize(directory, options = {})
  require 'fileutils'
  require 'tmpdir'
  require 'zlib'

  unless defined?(Builder::XChar) then
    raise "Gem::Indexer requires that the XML Builder library be installed:" +
          "\n\tgem install builder"
  end

  options = { :build_modern => true }.merge options

  @build_modern = options[:build_modern]

  @dest_directory = directory
  @directory = File.join(Dir.tmpdir, "gem_generate_index_#{$$}")

  marshal_name = "Marshal.#{Gem.marshal_version}"

  @master_index = File.join @directory, 'yaml'
  @marshal_index = File.join @directory, marshal_name

  @quick_dir = File.join @directory, 'quick'
  @quick_marshal_dir = File.join @quick_dir, marshal_name
  @quick_marshal_dir_base = File.join "quick", marshal_name # FIX: UGH

  @quick_index = File.join @quick_dir, 'index'
  @latest_index = File.join @quick_dir, 'latest_index'

  @specs_index = File.join @directory, "specs.#{Gem.marshal_version}"
  @latest_specs_index =
    File.join(@directory, "latest_specs.#{Gem.marshal_version}")
  @prerelease_specs_index =
    File.join(@directory, "prerelease_specs.#{Gem.marshal_version}")
  @dest_specs_index =
    File.join(@dest_directory, "specs.#{Gem.marshal_version}")
  @dest_latest_specs_index =
    File.join(@dest_directory, "latest_specs.#{Gem.marshal_version}")
  @dest_prerelease_specs_index =
    File.join(@dest_directory, "prerelease_specs.#{Gem.marshal_version}")

  @files = []
end

Public Instance Methods

abbreviate(spec) click to toggle source

Abbreviate the spec for downloading. Abbreviated specs are only used for searching, downloading and related activities and do not need deployment specific information (e.g. list of files). So we abbreviate the spec, making it much smaller for quicker downloads.

# File lib/rubygems/indexer.rb, line 103
def abbreviate(spec)
  spec.files = []
  spec.test_files = []
  spec.rdoc_options = []
  spec.extra_rdoc_files = []
  spec.cert_chain = []
  spec
end
build_indicies() click to toggle source

Build various indicies

# File lib/rubygems/indexer.rb, line 115
def build_indicies
  Gem::Specification.dirs = []
  Gem::Specification.add_specs(*map_gems_to_specs(gem_file_list))

  build_marshal_gemspecs
  build_modern_indicies if @build_modern

  compress_indicies
end
build_marshal_gemspecs() click to toggle source

Builds Marshal quick index gemspecs.

# File lib/rubygems/indexer.rb, line 128
def build_marshal_gemspecs
  count = Gem::Specification.count
  progress = ui.progress_reporter count,
                                  "Generating Marshal quick index gemspecs for #{count} gems",
                                  "Complete"

  files = []

  Gem.time 'Generated Marshal quick index gemspecs' do
    Gem::Specification.each do |spec|
      spec_file_name = "#{spec.original_name}.gemspec.rz"
      marshal_name = File.join @quick_marshal_dir, spec_file_name

      marshal_zipped = Gem.deflate Marshal.dump(spec)
      open marshal_name, 'wb' do |io| io.write marshal_zipped end

      files << marshal_name

      progress.updated spec.original_name
    end

    progress.done
  end

  @files << @quick_marshal_dir

  files
end
build_modern_index(index, file, name) click to toggle source

Build a single index for RubyGems 1.2 and newer

# File lib/rubygems/indexer.rb, line 160
def build_modern_index(index, file, name)
  say "Generating #{name} index"

  Gem.time "Generated #{name} index" do
    open(file, 'wb') do |io|
      specs = index.map do |*spec|
        # We have to splat here because latest_specs is an array, while the
        # others are hashes.
        spec = spec.flatten.last
        platform = spec.original_platform

        # win32-api-1.0.4-x86-mswin32-60
        unless String === platform then
          alert_warning "Skipping invalid platform in gem: #{spec.full_name}"
          next
        end

        platform = Gem::Platform::RUBY if platform.nil? or platform.empty?
        [spec.name, spec.version, platform]
      end

      specs = compact_specs(specs)
      Marshal.dump(specs, io)
    end
  end
end
build_modern_indicies() click to toggle source

Builds indicies for RubyGems 1.2 and newer. Handles full, latest, prerelease

# File lib/rubygems/indexer.rb, line 190
def build_modern_indicies
  prerelease, released = Gem::Specification.partition { |s|
    s.version.prerelease?
  }
  latest_specs = Gem::Specification.latest_specs

  build_modern_index(released.sort, @specs_index, 'specs')
  build_modern_index(latest_specs.sort, @latest_specs_index, 'latest specs')
  build_modern_index(prerelease.sort, @prerelease_specs_index,
                     'prerelease specs')

  @files += [@specs_index,
             "#{@specs_index}.gz",
             @latest_specs_index,
             "#{@latest_specs_index}.gz",
             @prerelease_specs_index,
             "#{@prerelease_specs_index}.gz"]
end
compact_specs(specs) click to toggle source

Compacts Marshal output for the specs index data source by using identical objects as much as possible.

# File lib/rubygems/indexer.rb, line 267
def compact_specs(specs)
  names = {}
  versions = {}
  platforms = {}

  specs.map do |(name, version, platform)|
    names[name] = name unless names.include? name
    versions[version] = version unless versions.include? version
    platforms[platform] = platform unless platforms.include? platform

    [names[name], versions[version], platforms[platform]]
  end
end
compress(filename, extension) click to toggle source

Compress filename with extension.

# File lib/rubygems/indexer.rb, line 284
def compress(filename, extension)
  data = Gem.read_binary filename

  zipped = Gem.deflate data

  open "#{filename}.#{extension}", 'wb' do |io|
    io.write zipped
  end
end
compress_indicies() click to toggle source

Compresses indicies on disk

# File lib/rubygems/indexer.rb, line 251
def compress_indicies
  say "Compressing indicies"

  Gem.time 'Compressed indicies' do
    if @build_modern then
      gzip @specs_index
      gzip @latest_specs_index
      gzip @prerelease_specs_index
    end
  end
end
gem_file_list() click to toggle source

List of gem file names to index.

# File lib/rubygems/indexer.rb, line 297
def gem_file_list
  Dir[File.join(@dest_directory, "gems", '*.gem')]
end
generate_index() click to toggle source

Builds and installs indicies.

# File lib/rubygems/indexer.rb, line 304
def generate_index
  make_temp_directories
  build_indicies
  install_indicies
rescue SignalException
ensure
  FileUtils.rm_rf @directory
end
gzip(filename) click to toggle source

Zlib::GzipWriter wrapper that gzips filename on disk.

# File lib/rubygems/indexer.rb, line 316
def gzip(filename)
  Zlib::GzipWriter.open "#{filename}.gz" do |io|
    io.write Gem.read_binary(filename)
  end
end
install_indicies() click to toggle source

Install generated indicies into the destination directory.

# File lib/rubygems/indexer.rb, line 325
def install_indicies
  verbose = Gem.configuration.really_verbose

  say "Moving index into production dir #{@dest_directory}" if verbose

  files = @files
  files.delete @quick_marshal_dir if files.include? @quick_dir

  if files.include? @quick_marshal_dir and not files.include? @quick_dir then
    files.delete @quick_marshal_dir

    dst_name = File.join(@dest_directory, @quick_marshal_dir_base)

    FileUtils.mkdir_p File.dirname(dst_name), :verbose => verbose
    FileUtils.rm_rf dst_name, :verbose => verbose
    FileUtils.mv(@quick_marshal_dir, dst_name,
                 :verbose => verbose, :force => true)
  end

  files = files.map do |path|
    path.sub(/^#{Regexp.escape @directory}\/?/, '') # HACK?
  end

  files.each do |file|
    src_name = File.join @directory, file
    dst_name = File.join @dest_directory, file

    FileUtils.rm_rf dst_name, :verbose => verbose
    FileUtils.mv(src_name, @dest_directory,
                 :verbose => verbose, :force => true)
  end
end
make_temp_directories() click to toggle source

Make directories for index generation

# File lib/rubygems/indexer.rb, line 361
def make_temp_directories
  FileUtils.rm_rf @directory
  FileUtils.mkdir_p @directory, :mode => 0700
  FileUtils.mkdir_p @quick_marshal_dir
end
map_gems_to_specs(gems) click to toggle source
# File lib/rubygems/indexer.rb, line 209
def map_gems_to_specs gems
  gems.map { |gemfile|
    if File.size(gemfile) == 0 then
      alert_warning "Skipping zero-length gem: #{gemfile}"
      next
    end

    begin
      spec = Gem::Package.new(gemfile).spec
      spec.loaded_from = gemfile

      # HACK: fuck this shit - borks all tests that use pl1
      # if File.basename(gemfile, ".gem") != spec.original_name then
      #   exp = spec.full_name
      #   exp << " (#{spec.original_name})" if
      #     spec.original_name != spec.full_name
      #   msg = "Skipping misnamed gem: #{gemfile} should be named #{exp}"
      #   alert_warning msg
      #   next
      # end

      abbreviate spec
      sanitize spec

      spec
    rescue SignalException => e
      alert_error "Received signal, exiting"
      raise
    rescue Exception => e
      msg = ["Unable to process #{gemfile}",
             "#{e.message} (#{e.class})",
             "\t#{e.backtrace.join "\n\t"}"].join("\n")
      alert_error msg
    end
  }.compact
end
paranoid(path, extension) click to toggle source

Ensure path and path with extension are identical.

# File lib/rubygems/indexer.rb, line 370
def paranoid(path, extension)
  data = Gem.read_binary path
  compressed_data = Gem.read_binary "#{path}.#{extension}"

  unless data == Gem.inflate(compressed_data) then
    raise "Compressed file #{compressed_path} does not match uncompressed file #{path}"
  end
end
sanitize(spec) click to toggle source

Sanitize the descriptive fields in the spec. Sometimes non-ASCII characters will garble the site index. Non-ASCII characters will be replaced by their XML entity equivalent.

# File lib/rubygems/indexer.rb, line 384
def sanitize(spec)
  spec.summary              = sanitize_string(spec.summary)
  spec.description          = sanitize_string(spec.description)
  spec.post_install_message = sanitize_string(spec.post_install_message)
  spec.authors              = spec.authors.collect { |a| sanitize_string(a) }

  spec
end
sanitize_string(string) click to toggle source

Sanitize a single string.

# File lib/rubygems/indexer.rb, line 396
def sanitize_string(string)
  return string unless string

  # HACK the #to_s is in here because RSpec has an Array of Arrays of
  # Strings for authors.  Need a way to disallow bad values on gemspec
  # generation.  (Probably won't happen.)
  string = string.to_s

  begin
    Builder::XChar.encode string
  rescue NameError, NoMethodError
    string.to_xs
  end
end
update_index() click to toggle source

Perform an in-place update of the repository from newly added gems.

# File lib/rubygems/indexer.rb, line 414
def update_index
  make_temp_directories

  specs_mtime = File.stat(@dest_specs_index).mtime
  newest_mtime = Time.at 0

  updated_gems = gem_file_list.select do |gem|
    gem_mtime = File.stat(gem).mtime
    newest_mtime = gem_mtime if gem_mtime > newest_mtime
    gem_mtime >= specs_mtime
  end

  if updated_gems.empty? then
    say 'No new gems'
    terminate_interaction 0
  end

  specs = map_gems_to_specs updated_gems
  prerelease, released = specs.partition { |s| s.version.prerelease? }

  Gem::Specification.dirs = []
  Gem::Specification.add_specs(*specs)

  files = build_marshal_gemspecs

  Gem.time 'Updated indexes' do
    update_specs_index released, @dest_specs_index, @specs_index
    update_specs_index released, @dest_latest_specs_index, @latest_specs_index
    update_specs_index(prerelease,
                       @dest_prerelease_specs_index,
                       @prerelease_specs_index)
  end

  compress_indicies

  verbose = Gem.configuration.really_verbose

  say "Updating production dir #{@dest_directory}" if verbose

  files << @specs_index
  files << "#{@specs_index}.gz"
  files << @latest_specs_index
  files << "#{@latest_specs_index}.gz"
  files << @prerelease_specs_index
  files << "#{@prerelease_specs_index}.gz"

  files = files.map do |path|
    path.sub(/^#{Regexp.escape @directory}\/?/, '') # HACK?
  end

  files.each do |file|
    src_name = File.join @directory, file
    dst_name = File.join @dest_directory, file # REFACTOR: duped above

    FileUtils.mv src_name, dst_name, :verbose => verbose,
                 :force => true

    File.utime newest_mtime, newest_mtime, dst_name
  end
end
update_specs_index(index, source, dest) click to toggle source

Combines specs in index and source then writes out a new copy to dest. For a latest index, does not ensure the new file is minimal.

# File lib/rubygems/indexer.rb, line 479
def update_specs_index(index, source, dest)
  specs_index = Marshal.load Gem.read_binary(source)

  index.each do |spec|
    platform = spec.original_platform
    platform = Gem::Platform::RUBY if platform.nil? or platform.empty?
    specs_index << [spec.name, spec.version, platform]
  end

  specs_index = compact_specs specs_index.uniq.sort

  open dest, 'wb' do |io|
    Marshal.dump specs_index, io
  end
end


class Gem::InstallError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::InstallError

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


module Gem::InstallUpdateOptions - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::InstallUpdateOptions

Mixin methods for install and update options for Gem::Commands

In Files

  • lib/rubygems/install_update_options.rb

Public Instance Methods

add_install_update_options() click to toggle source

Add the install/update options to the option parser.

# File lib/rubygems/install_update_options.rb, line 24
def add_install_update_options
  # TODO: use @parser.accept
  OptionParser.accept Gem::Security::Policy do |value|
    require 'rubygems/security'

    value = Gem::Security::Policies[value]
    valid = Gem::Security::Policies.keys.sort
    message = "#{value} (#{valid.join ', '} are valid)"
    raise OptionParser::InvalidArgument, message if value.nil?
    value
  end

  add_option(:"Install/Update", '-i', '--install-dir DIR',
             'Gem repository directory to get installed',
             'gems') do |value, options|
    options[:install_dir] = File.expand_path(value)
  end

  add_option(:"Install/Update", '-n', '--bindir DIR',
             'Directory where binary files are',
             'located') do |value, options|
    options[:bin_dir] = File.expand_path(value)
  end

  add_option(:"Install/Update",       '--[no-]document [TYPES]', Array,
             'Generate documentation for installed gems',
             'List the documentation types you wish to',
             'generate.  For example: rdoc,ri') do |value, options|
    options[:document] = case value
                         when nil   then %w[ri]
                         when false then []
                         else            value
                         end
  end

  add_option(:"Install/Update", '-N', '--no-document',
             'Disable documentation generation') do |value, options|
    options[:document] = []
  end

  add_option(:Deprecated, '--[no-]rdoc',
             'Generate RDoc for installed gems',
             'Use --document instead') do |value, options|
    if value then
      options[:document] << 'rdoc'
    else
      options[:document].delete 'rdoc'
    end

    options[:document].uniq!
  end

  add_option(:Deprecated, '--[no-]ri',
             'Generate ri data for installed gems.',
             'Use --document instead') do |value, options|
    if value then
      options[:document] << 'ri'
    else
      options[:document].delete 'ri'
    end

    options[:document].uniq!
  end

  add_option(:"Install/Update", '-E', '--[no-]env-shebang',
             "Rewrite the shebang line on installed",
             "scripts to use /usr/bin/env") do |value, options|
    options[:env_shebang] = value
  end

  add_option(:"Install/Update", '-f', '--[no-]force',
             'Force gem to install, bypassing dependency',
             'checks') do |value, options|
    options[:force] = value
  end

  add_option(:"Install/Update", '-w', '--[no-]wrappers',
             'Use bin wrappers for executables',
             'Not available on dosish platforms') do |value, options|
    options[:wrappers] = value
  end

  add_option(:"Install/Update", '-P', '--trust-policy POLICY',
             Gem::Security::Policy,
             'Specify gem trust policy') do |value, options|
    options[:security_policy] = value
  end

  add_option(:"Install/Update", '--ignore-dependencies',
             'Do not install any required dependent gems') do |value, options|
    options[:ignore_dependencies] = value
  end

  add_option(:"Install/Update",       '--[no-]format-executable',
             'Make installed executable names match ruby.',
             'If ruby is ruby18, foo_exec will be',
             'foo_exec18') do |value, options|
    options[:format_executable] = value
  end

  add_option(:"Install/Update",       '--[no-]user-install',
             'Install in user\s home directory instead',
             'of GEM_HOME.') do |value, options|
    options[:user_install] = value
  end

  add_option(:"Install/Update", "--development",
              "Install additional development",
              "dependencies") do |value, options|
    options[:development] = true
    options[:dev_shallow] = true
  end

  add_option(:"Install/Update", "--development-all",
              "Install development dependencies for all",
              "gems (including dev deps themselves)") do |value, options|
    options[:development] = true
    options[:dev_shallow] = false
  end

  add_option(:"Install/Update", "--conservative",
              "Don't attempt to upgrade gems already",
              "meeting version requirement") do |value, options|
    options[:conservative] = true
    options[:minimal_deps] = true
  end

  add_option(:"Install/Update", "--minimal-deps",
              "Don't upgrade any dependencies that already",
              "meet version requirements") do |value, options|
    options[:minimal_deps] = true
  end
end
install_update_defaults_str() click to toggle source

Default options for the gem install command.

# File lib/rubygems/install_update_options.rb, line 161
def install_update_defaults_str
  '--document=rdoc,ri --wrappers'
end


class Gem::Installer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Installer

The installer installs the files contained in the .gem into the Gem.home.

Gem::Installer does the work of putting files in all the right places on the filesystem including unpacking the gem into its gem dir, installing the gemspec in the specifications dir, storing the cached gem in the cache dir, and installing either wrappers or symlinks for executables.

The installer invokes pre and post install hooks. Hooks can be added either through a rubygems_plugin.rb file in an installed gem or via a rubygems/defaults/#{RUBY_ENGINE}.rb or rubygems/defaults/operating_system.rb file. See Gem.pre_install and Gem.post_install for details.

In Files

  • lib/rubygems/installer.rb
  • lib/rubygems/installer_test_case.rb

Parent

Object

Included Modules

  • Gem::UserInteraction

Constants

ENV_PATHS

Paths where env(1) might live. Some systems are broken and have it in /bin

Attributes

exec_format[W]

DOC: Missing docs or :nodoc:.

path_warning[RW]

True if we've warned about PATH not including Gem.bindir

bin_dir[RW]

The directory a gem's executables will be installed into

build_args[W]

Available through requiring rubygems/installer_test_case

env_shebang[W]

Available through requiring rubygems/installer_test_case

force[W]

Available through requiring rubygems/installer_test_case

format[W]

Available through requiring rubygems/installer_test_case

format_executable[W]

Available through requiring rubygems/installer_test_case

gem[R]

DOC: Missing docs or :nodoc:.

gem_dir[W]

Available through requiring rubygems/installer_test_case

gem_home[RW]

The gem repository the gem will be installed into

ignore_dependencies[W]

Available through requiring rubygems/installer_test_case

options[R]

The options passed when the Gem::Installer was instantiated.

security_policy[W]

Available through requiring rubygems/installer_test_case

spec[W]

Available through requiring rubygems/installer_test_case

wrappers[W]

Available through requiring rubygems/installer_test_case

Public Class Methods

exec_format() click to toggle source

Defaults to use Ruby's program prefix and suffix.

# File lib/rubygems/installer.rb, line 81
def exec_format
  @exec_format ||= Gem.default_exec_format
end
new(gem, options={}) click to toggle source

Constructs an Installer instance that will install the gem located at gem. options is a Hash with the following keys:

:#bin_dir

Where to put a bin wrapper if needed.

:development

Whether or not development dependencies should be installed.

:#env_shebang

Use /usr/bin/env in bin wrappers.

:force

Overrides all version checks and security policy checks, except for a signed-gems-only policy.

:#format_executable

Format the executable the same as the ruby executable. If your ruby is ruby18, foo_exec will be installed as foo_exec18.

:#ignore_dependencies

Don't raise if a dependency is missing.

:install_dir

The directory to install the gem into.

:#security_policy

Use the specified security policy. See Gem::Security

:user_install

Indicate that the gem should be unpacked into the users personal gem directory.

:only_install_dir

Only validate dependencies against what is in the install_dir

:wrappers

Install wrappers if true, symlinks if false.

:#build_args

An Array of arguments to pass to the extension builder process. If not set, then Gem::Command.build_args is used

# File lib/rubygems/installer.rb, line 110
def initialize(gem, options={})
  require 'fileutils'

  @gem = gem
  @options = options
  @package = Gem::Package.new @gem

  process_options

  @package.security_policy = @security_policy

  if options[:user_install] and not options[:unpack] then
    @gem_home = Gem.user_dir
    @bin_dir = Gem.bindir gem_home unless options[:bin_dir]
    check_that_user_bin_dir_is_in_path
  end
end

Public Instance Methods

app_script_text(bin_file_name) click to toggle source

Return the text for an application file.

# File lib/rubygems/installer.rb, line 602
  def app_script_text(bin_file_name)
    return <<-TEXT
#{shebang bin_file_name}
#
# This file was generated by RubyGems.
#
# The application '#{spec.name}' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = "#{Gem::Requirement.default}"

if ARGV.first
  str = ARGV.first
  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
  if str =~ /\\A_(.*)_\\z/
    version = $1
    ARGV.shift
  end
end

gem '#{spec.name}', version
load Gem.bin_path('#{spec.name}', '#{bin_file_name}', version)
TEXT
  end
build_extensions() click to toggle source

Builds extensions. Valid types of extensions are extconf.rb files, configure scripts and rakefiles or mkrf_conf files.

# File lib/rubygems/installer.rb, line 649
def build_extensions
  return if spec.extensions.empty?

  if @build_args.empty?
    say "Building native extensions.  This could take a while..."
  else
    say "Building native extensions with: '#{@build_args.join(' ')}'"
    say "This could take a while..."
  end

  dest_path = File.join gem_dir, spec.require_paths.first
  ran_rake = false # only run rake once

  spec.extensions.each do |extension|
    break if ran_rake
    results = []

    extension ||= ""
    extension_dir = File.join gem_dir, File.dirname(extension)

    builder = case extension
              when /extconf/ then
                Gem::Ext::ExtConfBuilder
              when /configure/ then
                Gem::Ext::ConfigureBuilder
              when /rakefile/, /mkrf_conf/ then
                ran_rake = true
                Gem::Ext::RakeBuilder
              when /CMakeLists.txt/ then
                Gem::Ext::CmakeBuilder
              else
                message = "No builder for extension '#{extension}'"
                extension_build_error extension_dir, message
              end

    begin
      FileUtils.mkdir_p dest_path

      CHDIR_MUTEX.synchronize do
        Dir.chdir extension_dir do
          results = builder.build(extension, gem_dir, dest_path,
                                  results, @build_args)

          say results.join("\n") if Gem.configuration.really_verbose
        end
      end
    rescue
      extension_build_error(extension_dir, results.join("\n"), $@)
    end
  end
end
check_that_user_bin_dir_is_in_path() click to toggle source

DOC: Missing docs or :nodoc:.

# File lib/rubygems/installer.rb, line 573
def check_that_user_bin_dir_is_in_path
  user_bin_dir = @bin_dir || Gem.bindir(gem_home)
  user_bin_dir = user_bin_dir.gsub(File::SEPARATOR, File::ALT_SEPARATOR) if
    File::ALT_SEPARATOR

  path = ENV['PATH']
  if Gem.win_platform? then
    path = path.downcase
    user_bin_dir = user_bin_dir.downcase
  end

  unless path.split(File::PATH_SEPARATOR).include? user_bin_dir then
    unless self.class.path_warning then
      alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t  gem executables will not run."
      self.class.path_warning = true
    end
  end
end
dir() click to toggle source

Return the target directory where the gem is to be installed. This directory is not guaranteed to be populated.

# File lib/rubygems/installer.rb, line 747
def dir
  gem_dir.to_s
end
ensure_dependencies_met() click to toggle source

DOC: Missing docs or :nodoc:.

# File lib/rubygems/installer.rb, line 535
def ensure_dependencies_met
  deps = spec.runtime_dependencies
  deps |= spec.development_dependencies if @development

  deps.each do |dep_gem|
    ensure_dependency spec, dep_gem
  end
end
ensure_dependency(spec, dependency) click to toggle source

Ensure that the dependency is satisfied by the current installation of gem. If it is not an exception is raised.

spec

Gem::Specification

dependency

Gem::Dependency

# File lib/rubygems/installer.rb, line 306
def ensure_dependency(spec, dependency)
  unless installation_satisfies_dependency? dependency then
    raise Gem::InstallError, "#{spec.name} requires #{dependency}"
  end
  true
end
ensure_loadable_spec() click to toggle source

Ensures the Gem::Specification written out for this gem is loadable upon installation.

# File lib/rubygems/installer.rb, line 502
def ensure_loadable_spec
  ruby = spec.to_ruby_for_cache
  ruby.untaint

  begin
    eval ruby
  rescue StandardError, SyntaxError => e
    raise Gem::InstallError,
          "The specification for #{spec.full_name} is corrupt (#{e.class})"
  end
end
ensure_required_ruby_version_met() click to toggle source

DOC: Missing docs or :nodoc:.

# File lib/rubygems/installer.rb, line 515
def ensure_required_ruby_version_met
  if rrv = spec.required_ruby_version then
    unless rrv.satisfied_by? Gem.ruby_version then
      raise Gem::InstallError, "#{spec.name} requires Ruby version #{rrv}."
    end
  end
end
ensure_required_rubygems_version_met() click to toggle source

DOC: Missing docs or :nodoc:.

# File lib/rubygems/installer.rb, line 524
def ensure_required_rubygems_version_met
  if rrgv = spec.required_rubygems_version then
    unless rrgv.satisfied_by? Gem.rubygems_version then
      raise Gem::InstallError,
        "#{spec.name} requires RubyGems version #{rrgv}. " +
        "Try 'gem update --system' to update RubyGems itself."
    end
  end
end
extension_build_error(build_dir, output, backtrace = nil) click to toggle source

Logs the build output in build_dir, then raises ExtensionBuildError.

# File lib/rubygems/installer.rb, line 704
  def extension_build_error(build_dir, output, backtrace = nil)
    gem_make_out = File.join build_dir, 'gem_make.out'

    open gem_make_out, 'wb' do |io| io.puts output end

    message = <<-EOF
ERROR: Failed to build gem native extension.

    #{output}

Gem files will remain installed in #{gem_dir} for inspection.
Results logged to #{gem_make_out}
EOF

    raise ExtensionBuildError, message, backtrace
  end
extract_files() click to toggle source

Reads the file index and extracts each file into the gem directory.

Ensures that files can't be installed outside the gem directory.

# File lib/rubygems/installer.rb, line 726
def extract_files
  @package.extract_files gem_dir
end
formatted_program_filename(filename) click to toggle source

Prefix and suffix the program filename the same as ruby.

# File lib/rubygems/installer.rb, line 733
def formatted_program_filename(filename)
  if @format_executable then
    self.class.exec_format % File.basename(filename)
  else
    filename
  end
end
gem_dir() click to toggle source

Lazy accessor for the spec's gem directory.

# File lib/rubygems/installer.rb, line 191
def gem_dir
  @gem_dir ||= File.join(gem_home, "gems", spec.full_name)
end
generate_bin() click to toggle source

DOC: Missing docs or :nodoc:.

# File lib/rubygems/installer.rb, line 365
def generate_bin
  return if spec.executables.nil? or spec.executables.empty?

  Dir.mkdir @bin_dir unless File.exist? @bin_dir
  raise Gem::FilePermissionError.new(@bin_dir) unless File.writable? @bin_dir

  spec.executables.each do |filename|
    filename.untaint
    bin_path = File.join gem_dir, spec.bindir, filename

    unless File.exist? bin_path then
      # TODO change this to a more useful warning
      warn "#{bin_path} maybe `gem pristine #{spec.name}` will fix it?"
      next
    end

    mode = File.stat(bin_path).mode | 0111
    FileUtils.chmod mode, bin_path

    check_executable_overwrite filename

    if @wrappers then
      generate_bin_script filename, @bin_dir
    else
      generate_bin_symlink filename, @bin_dir
    end

  end
end
generate_bin_script(filename, bindir) click to toggle source

Creates the scripts to run the applications in the gem.

# File lib/rubygems/installer.rb, line 402
def generate_bin_script(filename, bindir)
  bin_script_path = File.join bindir, formatted_program_filename(filename)

  FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers

  File.open bin_script_path, 'wb', 0755 do |file|
    file.print app_script_text(filename)
  end

  say bin_script_path if Gem.configuration.really_verbose

  generate_windows_script filename, bindir
end
generate_bin_symlink(filename, bindir) click to toggle source

Creates the symlinks to run the applications in the gem. Moves the symlink if the gem being installed has a newer version.

# File lib/rubygems/installer.rb, line 420
def generate_bin_symlink(filename, bindir)
  if Gem.win_platform? then
    alert_warning "Unable to use symlinks on Windows, installing wrapper"
    generate_bin_script filename, bindir
    return
  end

  src = File.join gem_dir, spec.bindir, filename
  dst = File.join bindir, formatted_program_filename(filename)

  if File.exist? dst then
    if File.symlink? dst then
      link = File.readlink(dst).split File::SEPARATOR
      cur_version = Gem::Version.create(link[-3].sub(/^.*-/, ''))
      return if spec.version < cur_version
    end
    File.unlink dst
  end

  FileUtils.symlink src, dst, :verbose => Gem.configuration.really_verbose
end
generate_windows_script(filename, bindir) click to toggle source

Creates windows .bat files for easy running of commands

# File lib/rubygems/installer.rb, line 352
def generate_windows_script(filename, bindir)
  if Gem.win_platform? then
    script_name = filename + ".bat"
    script_path = File.join bindir, File.basename(script_name)
    File.open script_path, 'w' do |file|
      file.puts windows_stub_script(bindir, filename)
    end

    say script_path if Gem.configuration.really_verbose
  end
end
install() click to toggle source

Installs the gem and returns a loaded Gem::Specification for the installed gem.

The gem will be installed with the following structure:

@gem_home/
  cache/<gem-version>.gem #=> a cached copy of the installed gem
  gems/<gem-version>/... #=> extracted files
  specifications/<gem-version>.gemspec #=> the Gem::Specification

# File lib/rubygems/installer.rb, line 215
def install
  pre_install_checks

  run_pre_install_hooks

  # Completely remove any previous gem files
  FileUtils.rm_rf gem_dir

  FileUtils.mkdir_p gem_dir

  extract_files

  build_extensions
  write_build_info_file
  run_post_build_hooks

  generate_bin
  write_spec
  write_cache_file

  say spec.post_install_message unless spec.post_install_message.nil?

  spec.loaded_from = spec_file

  Gem::Specification.add_spec spec unless Gem::Specification.include? spec

  run_post_install_hooks

  spec

# TODO This rescue is in the wrong place. What is raising this exception?
# move this rescue to around the code that actually might raise it.
rescue Zlib::GzipFile::Error
  raise Gem::InstallError, "gzip error installing #{gem}"
end
installation_satisfies_dependency?(dependency) click to toggle source

True if the gems in the system satisfy dependency.

# File lib/rubygems/installer.rb, line 316
def installation_satisfies_dependency?(dependency)
  return true if installed_specs.detect { |s| dependency.matches_spec? s }
  return false if @only_install_dir
  not dependency.matching_specs.empty?
end
installed_specs() click to toggle source

Return an Array of Specifications contained within the #gem_home we'll be installing into.

# File lib/rubygems/installer.rb, line 286
def installed_specs
  @specs ||= begin
    specs = []

    Dir[File.join(gem_home, "specifications", "*.gemspec")].each do |path|
      spec = Gem::Specification.load path.untaint
      specs << spec if spec
    end

    specs
  end
end
pre_install_checks() click to toggle source

Performs various checks before installing the gem such as the install repository is writable and its directories exist, required ruby and rubygems versions are met and that dependencies are installed.

Version and dependency checks are skipped if this install is forced.

The dependent check will be skipped this install is ignoring dependencies.

# File lib/rubygems/installer.rb, line 760
def pre_install_checks
  verify_gem_home options[:unpack]

  # If we're forcing the install then disable security unless the security
  # policy says that we only install signed gems.
  @security_policy = nil if
    @force and @security_policy and not @security_policy.only_signed

  ensure_loadable_spec

  Gem.ensure_gem_subdirectories gem_home

  return true if @force

  ensure_required_ruby_version_met
  ensure_required_rubygems_version_met
  ensure_dependencies_met unless @ignore_dependencies

  true
end
process_options() click to toggle source

DOC: Missing docs or :nodoc:.

# File lib/rubygems/installer.rb, line 545
def process_options
  @options = {
    :bin_dir      => nil,
    :env_shebang  => false,
    :force        => false,
    :install_dir  => Gem.dir,
    :only_install_dir => false
  }.merge options

  @env_shebang         = options[:env_shebang]
  @force               = options[:force]
  @gem_home            = options[:install_dir]
  @ignore_dependencies = options[:ignore_dependencies]
  @format_executable   = options[:format_executable]
  @security_policy     = options[:security_policy]
  @wrappers            = options[:wrappers]
  @only_install_dir    = options[:only_install_dir]

  # If the user has asked for the gem to be installed in a directory that is
  # the system gem directory, then use the system bin directory, else create
  # (or use) a new bin dir under the gem_home.
  @bin_dir             = options[:bin_dir] || Gem.bindir(gem_home)
  @development         = options[:development]

  @build_args          = options[:build_args] || Gem::Command.build_args
end
shebang(bin_file_name) click to toggle source

Generates a #! line for bin_file_name's wrapper copying arguments if necessary.

If the :custom_shebang config is set, then it is used as a template for how to create the shebang used for to run a gem's executables.

The template supports 4 expansions:

$env    the path to the unix env utility
$ruby   the path to the currently running ruby interpreter
$exec   the path to the gem's executable
$name   the name of the gem the executable is for
# File lib/rubygems/installer.rb, line 457
def shebang(bin_file_name)
  ruby_name = Gem::ConfigMap[:ruby_install_name] if @env_shebang
  path = File.join gem_dir, spec.bindir, bin_file_name
  first_line = File.open(path, "rb") {|file| file.gets}

  if /\A#!/ =~ first_line then
    # Preserve extra words on shebang line, like "-w".  Thanks RPA.
    shebang = first_line.sub(/\A\#!.*?ruby\S*((\s+\S+)+)/, "#!#{Gem.ruby}")
    opts = $1
    shebang.strip! # Avoid nasty ^M issues.
  end

  if which = Gem.configuration[:custom_shebang]
    # replace bin_file_name with "ruby" to avoid endless loops
    which = which.gsub(/ #{bin_file_name}$/," #{Gem::ConfigMap[:ruby_install_name]}")

    which = which.gsub(/\$(\w+)/) do
      case $1
      when "env"
        @env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
      when "ruby"
        "#{Gem.ruby}#{opts}"
      when "exec"
        bin_file_name
      when "name"
        spec.name
      end
    end

    "#!#{which}"
  elsif not ruby_name then
    "#!#{Gem.ruby}#{opts}"
  elsif opts then
    "#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
  else
    # Create a plain shebang line.
    @env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
    "#!#{@env_path} #{ruby_name}"
  end
end
spec() click to toggle source

Lazy accessor for the installer's spec.

# File lib/rubygems/installer.rb, line 198
def spec
  @spec ||= @package.spec
rescue Gem::Package::Error => e
  raise Gem::InstallError, "invalid gem: #{e.message}"
end
spec_file() click to toggle source

The location of of the spec file that is installed.

# File lib/rubygems/installer.rb, line 334
def spec_file
  File.join gem_home, "specifications", "#{spec.full_name}.gemspec"
end
unpack(directory) click to toggle source

Unpacks the gem into the given directory.

# File lib/rubygems/installer.rb, line 325
def unpack(directory)
  @gem_dir = directory
  extract_files
end
verify_gem_home(unpack = false) click to toggle source

DOC: Missing docs or :nodoc:.

# File lib/rubygems/installer.rb, line 593
def verify_gem_home(unpack = false)
  FileUtils.mkdir_p gem_home
  raise Gem::FilePermissionError, gem_home unless
    unpack or File.writable?(gem_home)
end
windows_stub_script(bindir, bin_file_name) click to toggle source

return the stub script text used to launch the true ruby script

# File lib/rubygems/installer.rb, line 633
  def windows_stub_script(bindir, bin_file_name)
    ruby = File.basename(Gem.ruby).chomp('"')
    return <<-TEXT
@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
@"#{ruby}" "%~dpn0" %*
TEXT
  end
write_build_info_file() click to toggle source

Writes the file containing the arguments for building this gem's extensions.

# File lib/rubygems/installer.rb, line 785
def write_build_info_file
  return if @build_args.empty?

  build_info_dir = File.join gem_home, 'build_info'

  FileUtils.mkdir_p build_info_dir

  build_info_file = File.join build_info_dir, "#{spec.full_name}.info"

  open build_info_file, 'w' do |io|
    @build_args.each do |arg|
      io.puts arg
    end
  end
end
write_cache_file() click to toggle source

Writes the .gem file to the cache directory

# File lib/rubygems/installer.rb, line 804
def write_cache_file
  cache_file = File.join gem_home, 'cache', spec.file_name

  FileUtils.cp @gem, cache_file unless File.exist? cache_file
end
write_spec() click to toggle source

Writes the .gemspec specification (in Ruby) to the gem home's specifications directory.

# File lib/rubygems/installer.rb, line 342
def write_spec
  open spec_file, 'w' do |file|
    file.puts spec.to_ruby_for_cache
    file.fsync rescue nil # for filesystems without fsync(2)
  end
end


class Gem::Installer::ExtensionBuildError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Installer::ExtensionBuildError

Raised when there is an error while building extensions.

In Files

  • lib/rubygems/installer.rb

Parent

Gem::InstallError


class Gem::InstallerTestCase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::InstallerTestCase

A test case for Gem::Installer.

In Files

  • lib/rubygems/installer_test_case.rb

Parent

Gem::TestCase

Public Instance Methods

setup() click to toggle source
@gem

the path to a built gem from @spec

@user_spec

the path to a built gem from @user_spec

@installer

a Gem::Installer for the @spec that installs into @gemhome

@user_installer

a Gem::Installer for the @user_spec that installs into Gem.user_dir

# File lib/rubygems/installer_test_case.rb, line 90
def setup
  super

  @spec = quick_gem 'a' do |spec|
    util_make_exec spec
  end

  @user_spec = quick_gem 'b' do |spec|
    util_make_exec spec
  end

  util_build_gem @spec
  util_build_gem @user_spec

  @gem = @spec.cache_file
  @user_gem = @user_spec.cache_file

  @installer      = util_installer @spec, @gemhome
  @user_installer = util_installer @user_spec, Gem.user_dir, :user
end
util_inst_bindir() click to toggle source

The path where installed executables live

# File lib/rubygems/installer_test_case.rb, line 124
def util_inst_bindir
  File.join @gemhome, "bin"
end
util_installer(spec, gem_home, user=false) click to toggle source

Creates an installer for spec that will install into gem_home. If user is true a user-install will be performed.

# File lib/rubygems/installer_test_case.rb, line 189
def util_installer(spec, gem_home, user=false)
  Gem::Installer.new(spec.cache_file,
                     :install_dir => gem_home,
                     :user_install => user)
end
util_make_exec(spec = @spec, shebang = " click to toggle source

Adds an executable named “executable” to spec with the given shebang.

The executable is also written to the bin dir in @tmpdir and the installed gem directory for spec.

# File lib/rubygems/installer_test_case.rb, line 134
def util_make_exec(spec = @spec, shebang = "#!/usr/bin/ruby")
  spec.executables = %w[executable]
  spec.files << 'bin/executable'

  exec_path = spec.bin_file "executable"
  write_file exec_path do |io|
    io.puts shebang
  end

  bin_path = File.join @tempdir, "bin", "executable"
  write_file bin_path do |io|
    io.puts shebang
  end
end
util_setup_gem(ui = @ui) click to toggle source

Builds the @spec gem and returns an installer for it. The built gem includes:

bin/executable
lib/code.rb
ext/a/mkrf_conf.rb
# File lib/rubygems/installer_test_case.rb, line 157
def util_setup_gem(ui = @ui) # HACK fix use_ui to make this automatic
  @spec.files << File.join('lib', 'code.rb')
  @spec.extensions << File.join('ext', 'a', 'mkrf_conf.rb')

  Dir.chdir @tempdir do
    FileUtils.mkdir_p 'bin'
    FileUtils.mkdir_p 'lib'
    FileUtils.mkdir_p File.join('ext', 'a')
    File.open File.join('bin', 'executable'), 'w' do |f|
      f.puts "raise 'ran executable'"
    end
    File.open File.join('lib', 'code.rb'), 'w' do |f| f.puts '1' end
    File.open File.join('ext', 'a', 'mkrf_conf.rb'), 'w' do |f|
      f << <<-EOF
        File.open 'Rakefile', 'w' do |rf| rf.puts "task :default" end
      EOF
    end

    use_ui ui do
      FileUtils.rm_f @gem

      @gem = Gem::Package.build @spec
    end
  end

  @installer = Gem::Installer.new @gem
end


class Gem::InvalidSpecificationException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::InvalidSpecificationException

Potentially raised when a specification is validated.

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::LoadError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::LoadError

Raised when RubyGems is unable to load or activate a gem. Contains the name and version requirements of the gem that either conflicts with already activated gems or that RubyGems is otherwise unable to activate.

In Files

  • lib/rubygems/errors.rb

Parent

LoadError

Attributes

name[RW]

Name of gem

requirement[RW]

Version requirement of gem


module Gem::LocalRemoteOptions - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::LocalRemoteOptions

Mixin methods for local and remote Gem::Command options.

In Files

  • lib/rubygems/local_remote_options.rb

Public Instance Methods

accept_uri_http() click to toggle source

Allows OptionParser to handle HTTP URIs.

# File lib/rubygems/local_remote_options.rb, line 18
def accept_uri_http
  OptionParser.accept URI::HTTP do |value|
    begin
      uri = URI.parse value
    rescue URI::InvalidURIError
      raise OptionParser::InvalidArgument, value
    end

    unless ['http', 'https', 'file'].include?(uri.scheme)
       raise OptionParser::InvalidArgument, value
    end

    value
  end
end
add_bulk_threshold_option() click to toggle source

Add the –bulk-threshold option

# File lib/rubygems/local_remote_options.rb, line 63
def add_bulk_threshold_option
  add_option(:"Local/Remote", '-B', '--bulk-threshold COUNT',
             "Threshold for switching to bulk",
             "synchronization (default #{Gem.configuration.bulk_threshold})") do
    |value, options|
    Gem.configuration.bulk_threshold = value.to_i
  end
end
add_clear_sources_option() click to toggle source

Add the –clear-sources option

# File lib/rubygems/local_remote_options.rb, line 75
def add_clear_sources_option
  add_option(:"Local/Remote", '--clear-sources',
             'Clear the gem sources') do |value, options|

    Gem.sources = nil
    options[:sources_cleared] = true
  end
end
add_local_remote_options() click to toggle source

Add local/remote options to the command line parser.

# File lib/rubygems/local_remote_options.rb, line 37
def add_local_remote_options
  add_option(:"Local/Remote", '-l', '--local',
             'Restrict operations to the LOCAL domain') do |value, options|
    options[:domain] = :local
  end

  add_option(:"Local/Remote", '-r', '--remote',
    'Restrict operations to the REMOTE domain') do |value, options|
    options[:domain] = :remote
  end

  add_option(:"Local/Remote", '-b', '--both',
             'Allow LOCAL and REMOTE operations') do |value, options|
    options[:domain] = :both
  end

  add_bulk_threshold_option
  add_clear_sources_option
  add_source_option
  add_proxy_option
  add_update_sources_option
end
add_proxy_option() click to toggle source

Add the –http-proxy option

# File lib/rubygems/local_remote_options.rb, line 87
def add_proxy_option
  accept_uri_http

  add_option(:"Local/Remote", '-p', '--[no-]http-proxy [URL]', URI::HTTP,
             'Use HTTP proxy for remote operations') do |value, options|
    options[:http_proxy] = (value == false) ? :no_proxy : value
    Gem.configuration[:http_proxy] = options[:http_proxy]
  end
end
add_source_option() click to toggle source

Add the –source option

# File lib/rubygems/local_remote_options.rb, line 100
def add_source_option
  accept_uri_http

  add_option(:"Local/Remote", '--source URL', URI::HTTP,
             'Add URL as a remote source for gems') do |source, options|

    source << '/' if source !~ /\/\z/

    if options.delete :sources_cleared then
      Gem.sources = [source]
    else
      Gem.sources << source unless Gem.sources.include?(source)
    end
  end
end
add_update_sources_option() click to toggle source

Add the –update-sources option

# File lib/rubygems/local_remote_options.rb, line 119
def add_update_sources_option
  add_option(:Deprecated, '-u', '--[no-]update-sources',
             'Update local source cache') do |value, options|
    Gem.configuration.update_sources = value
  end
end
both?() click to toggle source

Is fetching of local and remote information enabled?

# File lib/rubygems/local_remote_options.rb, line 129
def both?
  options[:domain] == :both
end
local?() click to toggle source

Is local fetching enabled?

# File lib/rubygems/local_remote_options.rb, line 136
def local?
  options[:domain] == :local || options[:domain] == :both
end
remote?() click to toggle source

Is remote fetching enabled?

# File lib/rubygems/local_remote_options.rb, line 143
def remote?
  options[:domain] == :remote || options[:domain] == :both
end


class Gem::MockGemUi - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::MockGemUi

This Gem::StreamUI subclass records input and output to StringIO for retrieval during tests.

In Files

  • lib/rubygems/mock_gem_ui.rb

Parent

Gem::StreamUI

Public Class Methods

new(input = "") click to toggle source
# File lib/rubygems/mock_gem_ui.rb, line 44
def initialize(input = "")
  ins = StringIO.new input
  outs = StringIO.new
  errs = StringIO.new

  ins.extend TTY
  outs.extend TTY
  errs.extend TTY

  super ins, outs, errs, true

  @terminated = false
end

Public Instance Methods

ask(question) click to toggle source
# File lib/rubygems/mock_gem_ui.rb, line 58
def ask question
  raise InputEOFError, question if @ins.eof?

  super
end
error() click to toggle source
# File lib/rubygems/mock_gem_ui.rb, line 72
def error
  @errs.string
end
input() click to toggle source
# File lib/rubygems/mock_gem_ui.rb, line 64
def input
  @ins.string
end
output() click to toggle source
# File lib/rubygems/mock_gem_ui.rb, line 68
def output
  @outs.string
end
terminate_interaction(status=0) click to toggle source
# File lib/rubygems/mock_gem_ui.rb, line 80
def terminate_interaction(status=0)
  @terminated = true

  raise TermError, status if status != 0
  raise SystemExitException
end
terminated?() click to toggle source
# File lib/rubygems/mock_gem_ui.rb, line 76
def terminated?
  @terminated
end


class Gem::MockGemUi::InputEOFError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::MockGemUi::InputEOFError

Raised when you haven't provided enough input to your MockGemUi

In Files

  • lib/rubygems/mock_gem_ui.rb

Parent

RuntimeError

Public Class Methods

new(question) click to toggle source
# File lib/rubygems/mock_gem_ui.rb, line 14
def initialize question
  super "Out of input for MockGemUi on #{question.inspect}"
end


class Gem::MockGemUi::SystemExitException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::MockGemUi::SystemExitException

In Files

  • lib/rubygems/mock_gem_ui.rb

Parent

RuntimeError


module Gem::MockGemUi::TTY - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::MockGemUi::TTY

In Files

  • lib/rubygems/mock_gem_ui.rb

Attributes

tty[RW]

Public Instance Methods

noecho() { |self| ... } click to toggle source
# File lib/rubygems/mock_gem_ui.rb, line 39
def noecho
  yield self
end
tty?() click to toggle source
# File lib/rubygems/mock_gem_ui.rb, line 34
def tty?()
  @tty = true unless defined?(@tty)
  @tty
end


class Gem::MockGemUi::TermError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::MockGemUi::TermError

In Files

  • lib/rubygems/mock_gem_ui.rb

Parent

RuntimeError

Attributes

exit_code[R]

Public Class Methods

new(exit_code) click to toggle source
# File lib/rubygems/mock_gem_ui.rb, line 23
def initialize exit_code
  super
  @exit_code = exit_code
end


class Gem::NameTuple - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::NameTuple

In Files

  • lib/rubygems/name_tuple.rb

Parent

Object

Included Modules

  • Comparable

Attributes

name[R]
platform[R]
version[R]

Public Class Methods

from_list(list) click to toggle source

Turn an array of [name, version, platform] into an array of NameTuple objects.

# File lib/rubygems/name_tuple.rb, line 26
def self.from_list list
  list.map { |t| new(*t) }
end
new(name, version, platform="ruby") click to toggle source
# File lib/rubygems/name_tuple.rb, line 9
def initialize(name, version, platform="ruby")
  @name = name
  @version = version

  unless platform.kind_of? Gem::Platform
    platform = "ruby" if !platform or platform.empty?
  end

  @platform = platform
end
null() click to toggle source

A null NameTuple, ie name=nil, version=0

# File lib/rubygems/name_tuple.rb, line 41
def self.null
  new nil, Gem::Version.new(0), nil
end
to_basic(list) click to toggle source

Turn an array of NameTuple objects back into an array of

name, version, platform

tuples.

# File lib/rubygems/name_tuple.rb, line 34
def self.to_basic list
  list.map { |t| t.to_a }
end

Public Instance Methods

<=>(other) click to toggle source
# File lib/rubygems/name_tuple.rb, line 81
def <=> other
  to_a <=> other.to_a
end
==(other) click to toggle source

Compare with other. Supports another NameTuple or an Array in the [name, version, platform] format.

# File lib/rubygems/name_tuple.rb, line 91
def == other
  case other
  when self.class
    @name == other.name and
      @version == other.version and
      @platform == other.platform
  when Array
    to_a == other
  else
    false
  end
end
Also aliased as: eql?
eql?(other) click to toggle source
Alias for: ==
hash() click to toggle source
# File lib/rubygems/name_tuple.rb, line 106
def hash
  to_a.hash
end
match_platform?() click to toggle source

Indicate if this NameTuple matches the current platform.

# File lib/rubygems/name_tuple.rb, line 48
def match_platform?
  Gem::Platform.match @platform
end
prerelease?() click to toggle source

Indicate if this NameTuple is for a prerelease version.

# File lib/rubygems/name_tuple.rb, line 54
def prerelease?
  @version.prerelease?
end
spec_name() click to toggle source

Return the name that the gemspec file would be

# File lib/rubygems/name_tuple.rb, line 61
def spec_name
  case @platform
  when nil, 'ruby', ''
    "#{@name}-#{@version}.gemspec"
  else
    "#{@name}-#{@version}-#{@platform}.gemspec"
  end
end
to_a() click to toggle source

Convert back to the [name, version, platform] tuple

# File lib/rubygems/name_tuple.rb, line 73
def to_a
  [@name, @version, @platform]
end
to_s() click to toggle source
# File lib/rubygems/name_tuple.rb, line 77
def to_s
  "#<Gem::NameTuple #{@name}, #{@version}, #{@platform}>"
end


class Gem::NoAliasYAMLTree - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::NoAliasYAMLTree

In Files

  • lib/rubygems/psych_tree.rb

Parent

Psych::Visitors::YAMLTree

Public Class Methods

create() click to toggle source
# File lib/rubygems/psych_tree.rb, line 4
def self.create
  new({})
end

Public Instance Methods

register(target, obj) click to toggle source

Noop this out so there are no anchors

# File lib/rubygems/psych_tree.rb, line 16
def register(target, obj)
end
visit_String(str) click to toggle source
# File lib/rubygems/psych_tree.rb, line 8
def visit_String(str)
  return super unless str == '=' # or whatever you want

  quote = Psych::Nodes::Scalar::SINGLE_QUOTED
  @emitter.scalar str, nil, nil, false, true, quote
end


class Gem::OperationNotSupportedError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::OperationNotSupportedError

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::Package - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package

In Files

  • lib/rubygems/package.rb

Parent

Object

Included Modules

  • Gem::UserInteraction

Public Class Methods

build(spec, skip_validation=false) click to toggle source
# File lib/rubygems/package.rb, line 105
def self.build spec, skip_validation=false
  gem_file = spec.file_name

  package = new gem_file
  package.spec = spec
  package.build skip_validation

  gem_file
end
new(gem) click to toggle source

Creates a new Gem::Package for the file at gem.

If gem is an existing file in the old format a Gem::Package::Old will be returned.

# File lib/rubygems/package.rb, line 121
def self.new gem
  return super unless Gem::Package == self
  return super unless File.exist? gem

  start = File.read gem, 20

  return super unless start
  return super unless start.include? 'MD5SUM ='

  Gem::Package::Old.new gem
end

Public Instance Methods

add_checksums(tar) click to toggle source

Adds a checksum for each entry in the gem to checksums.yaml.gz.

# File lib/rubygems/package.rb, line 153
def add_checksums tar
  Gem.load_yaml

  checksums_by_algorithm = Hash.new { |h, algorithm| h[algorithm] = {} }

  @checksums.each do |name, digests|
    digests.each do |algorithm, digest|
      checksums_by_algorithm[algorithm][name] = digest.hexdigest
    end
  end

  tar.add_file_signed 'checksums.yaml.gz', 0444, @signer do |io|
    gzip_to io do |gz_io|
      YAML.dump checksums_by_algorithm, gz_io
    end
  end
end
build(skip_validation = false) click to toggle source

Builds this package based on the specification set by spec=

# File lib/rubygems/package.rb, line 220
  def build skip_validation = false
    Gem.load_yaml
    require 'rubygems/security'

    @spec.mark_version
    @spec.validate unless skip_validation

    setup_signer

    open @gem, 'wb' do |gem_io|
      Gem::Package::TarWriter.new gem_io do |gem|
        add_metadata gem
        add_contents gem
        add_checksums gem
      end
    end

    say <<-EOM
  Successfully built RubyGem
  Name: #{@spec.name}
  Version: #{@spec.version}
  File: #{File.basename @spec.cache_file}
EOM
  ensure
    @signer = nil
  end
contents() click to toggle source

A list of file names contained in this gem

# File lib/rubygems/package.rb, line 250
def contents
  return @contents if @contents

  verify unless @spec

  @contents = []

  open @gem, 'rb' do |io|
    gem_tar = Gem::Package::TarReader.new io

    gem_tar.each do |entry|
      next unless entry.full_name == 'data.tar.gz'

      open_tar_gz entry do |pkg_tar|
        pkg_tar.each do |contents_entry|
          @contents << contents_entry.full_name
        end
      end

      return @contents
    end
  end
end
extract_files(destination_dir) click to toggle source

Extracts the files in this package into destination_dir

# File lib/rubygems/package.rb, line 301
def extract_files destination_dir
  verify unless @spec

  FileUtils.mkdir_p destination_dir

  open @gem, 'rb' do |io|
    reader = Gem::Package::TarReader.new io

    reader.each do |entry|
      next unless entry.full_name == 'data.tar.gz'

      extract_tar_gz entry, destination_dir

      return # ignore further entries
    end
  end
end
gzip_to(io) { |gz_io| ... } click to toggle source

Gzips content written to gz_io to io.

# File lib/rubygems/package.rb, line 351
def gzip_to io # :yields: gz_io
  gz_io = Zlib::GzipWriter.new io, Zlib::BEST_COMPRESSION
  gz_io.mtime = @build_time

  yield gz_io
ensure
  gz_io.close
end
read_checksums(gem) click to toggle source

Reads and loads checksums.yaml.gz from the tar file gem

# File lib/rubygems/package.rb, line 415
def read_checksums gem
  Gem.load_yaml

  @checksums = gem.seek 'checksums.yaml.gz' do |entry|
    Zlib::GzipReader.wrap entry do |gz_io|
      YAML.load gz_io.read
    end
  end
end
setup_signer() click to toggle source

Prepares the gem for signing and checksum generation. If a signing certificate and key are not present only checksum generation is set up.

# File lib/rubygems/package.rb, line 429
def setup_signer
  if @spec.signing_key then
    @signer = Gem::Security::Signer.new @spec.signing_key, @spec.cert_chain
    @spec.signing_key = nil
    @spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_s }
  else
    @signer = Gem::Security::Signer.new nil, nil
    @spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_pem } if
      @signer.cert_chain
  end
end
spec() click to toggle source

The spec for this gem.

If this is a package for a built gem the spec is loaded from the gem and returned. If this is a package for a gem being built the provided spec is returned.

# File lib/rubygems/package.rb, line 448
def spec
  verify unless @spec

  @spec
end
verify() click to toggle source

Verifies that this gem:

  • Contains a valid gem specification

  • Contains a contents archive

  • The contents archive is not corrupt

After verification the gem specification from the gem is available from spec

# File lib/rubygems/package.rb, line 464
def verify
  @files     = []
  @spec      = nil

  open @gem, 'rb' do |io|
    Gem::Package::TarReader.new io do |reader|
      read_checksums reader

      verify_files reader
    end
  end

  verify_checksums @digests, @checksums

  @security_policy.verify_signatures @spec, @digests, @signatures if
    @security_policy

  true
rescue Gem::Security::Exception
  @spec = nil
  @files = []
  raise
rescue Errno::ENOENT => e
  raise Gem::Package::FormatError.new e.message
rescue Gem::Package::TarInvalidError => e
  raise Gem::Package::FormatError.new e.message, @gem
end
verify_files(gem) click to toggle source

Verifies the files of the gem

# File lib/rubygems/package.rb, line 514
def verify_files gem
  gem.each do |entry|
    file_name = entry.full_name
    @files << file_name

    case file_name
    when /\.sig$/ then
      @signatures[$`] = entry.read if @security_policy
      next
    else
      digest entry
    end

    case file_name
    when /^metadata(.gz)?$/ then
      load_spec entry
    when 'data.tar.gz' then
      verify_gz entry
    end
  end

  unless @spec then
    raise Gem::Package::FormatError.new 'package metadata is missing', @gem
  end

  unless @files.include? 'data.tar.gz' then
    raise Gem::Package::FormatError.new                'package content (data.tar.gz) is missing', @gem
  end
end

Protected Instance Methods

initialize(gem) click to toggle source

Creates a new package that will read or write to the file gem.

# File lib/rubygems/package.rb, line 136
def initialize gem # :notnew:
  @gem = gem

  @build_time      = Time.now
  @checksums       = {}
  @contents        = nil
  @digests         = Hash.new { |h, algorithm| h[algorithm] = {} }
  @files           = nil
  @security_policy = nil
  @signatures      = {}
  @signer          = nil
  @spec            = nil
end


class Gem::Package::DigestIO - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::DigestIO

IO wrapper that creates digests of contents written to the IO it wraps.

In Files

  • lib/rubygems/package/digest_io.rb

Parent

Object

Attributes

digests[R]

Collected digests for wrapped writes.

{
  'SHA1'   => #<OpenSSL::Digest: [...]>,
  'SHA512' => #<OpenSSL::Digest: [...]>,
}

Public Class Methods

new(io, digests) click to toggle source

Creates a new DigestIO instance. Using ::wrap is recommended, see the ::wrap documentation for documentation of io and digests.

# File lib/rubygems/package/digest_io.rb, line 45
def initialize io, digests
  @io = io
  @digests = digests
end
wrap(io, digests) { |digest_io| ... } click to toggle source

Wraps io and updates digest for each of the digest algorithms in the digests Hash. Returns the digests hash. Example:

io = StringIO.new
digests = {
  'SHA1'   => OpenSSL::Digest.new('SHA1'),
  'SHA512' => OpenSSL::Digest.new('SHA512'),
}

Gem::Package::DigestIO.wrap io, digests do |digest_io|
  digest_io.write "hello"
end

digests['SHA1'].hexdigest   #=> "aaf4c61d[...]"
digests['SHA512'].hexdigest #=> "9b71d224[...]"

# File lib/rubygems/package/digest_io.rb, line 33
def self.wrap io, digests
  digest_io = new io, digests

  yield digest_io

  return digests
end

Public Instance Methods

write(data) click to toggle source

Writes data to the underlying IO and updates the digests

# File lib/rubygems/package/digest_io.rb, line 53
def write data
  result = @io.write data

  @digests.each do |_, digest|
    digest << data
  end

  result
end


class Gem::Package::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::Error

In Files

  • lib/rubygems/package.rb

Parent

Gem::Exception


class Gem::Package::FormatError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::FormatError

In Files

  • lib/rubygems/package.rb

Parent

Gem::Package::Error

Attributes

path[R]

Public Class Methods

new(message, path = nil) click to toggle source
# File lib/rubygems/package.rb, line 56
def initialize message, path = nil
  @path = path

  message << " in #{path}" if path

  super message
end


class Gem::Package::NonSeekableIO - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::NonSeekableIO

In Files

  • lib/rubygems/package.rb

Parent

Gem::Package::Error


class Gem::Package::Old - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::Old

The format class knows the guts of the ancient .gem file format and provides the capability to read such ancient gems.

Please pretend this doesn't exist.

In Files

  • lib/rubygems/package/old.rb

Parent

Gem::Package

Public Class Methods

new(gem) click to toggle source

Creates a new old-format package reader for gem. Old-format packages cannot be written.

# File lib/rubygems/package/old.rb, line 21
def initialize gem
  require 'fileutils'
  require 'zlib'
  Gem.load_yaml

  @contents        = nil
  @gem             = gem
  @security_policy = nil
  @spec            = nil
end

Public Instance Methods

contents() click to toggle source

A list of file names contained in this gem

# File lib/rubygems/package/old.rb, line 35
def contents
  verify

  return @contents if @contents

  open @gem, 'rb' do |io|
    read_until_dashes io # spec
    header = file_list io

    @contents = header.map { |file| file['path'] }
  end
end
extract_files(destination_dir) click to toggle source

Extracts the files in this package into destination_dir

# File lib/rubygems/package/old.rb, line 51
def extract_files destination_dir
  verify

  errstr = "Error reading files from gem"

  open @gem, 'rb' do |io|
    read_until_dashes io # spec
    header = file_list io
    raise Gem::Exception, errstr unless header

    header.each do |entry|
      full_name = entry['path']

      destination = install_location full_name, destination_dir

      file_data = ''

      read_until_dashes io do |line|
        file_data << line
      end

      file_data = file_data.strip.unpack("m")[0]
      file_data = Zlib::Inflate.inflate file_data

      raise Gem::Package::FormatError, "#{full_name} in #{@gem} is corrupt" if
        file_data.length != entry['size'].to_i

      FileUtils.rm_rf destination

      FileUtils.mkdir_p File.dirname destination

      open destination, 'wb', entry['mode'] do |out|
        out.write file_data
      end

      say destination if Gem.configuration.really_verbose
    end
  end
rescue Zlib::DataError
  raise Gem::Exception, errstr
end
spec() click to toggle source

The specification for this gem

# File lib/rubygems/package/old.rb, line 132
def spec
  verify

  return @spec if @spec

  yaml = ''

  open @gem, 'rb' do |io|
    skip_ruby io
    read_until_dashes io do |line|
      yaml << line
    end
  end

  yaml_error = if RUBY_VERSION < '1.9' then
                 YAML::ParseError
               elsif YAML::ENGINE.yamler == 'syck' then
                 YAML::ParseError
               else
                 YAML::SyntaxError
               end

  begin
    @spec = Gem::Specification.from_yaml yaml
  rescue yaml_error => e
    raise Gem::Exception, "Failed to parse gem specification out of gem file"
  end
rescue ArgumentError => e
  raise Gem::Exception, "Failed to parse gem specification out of gem file"
end
verify() click to toggle source

Raises an exception if a security policy that verifies data is active. Old format gems cannot be verified as signed.

# File lib/rubygems/package/old.rb, line 167
def verify
  return true unless @security_policy

  raise Gem::Security::Exception,
        'old format gems do not contain signatures and cannot be verified' if
    @security_policy.verify_data

  true
end


class Gem::Package::PathError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::PathError

In Files

  • lib/rubygems/package.rb

Parent

Gem::Package::Error

Public Class Methods

new(destination, destination_dir) click to toggle source
# File lib/rubygems/package.rb, line 67
def initialize destination, destination_dir
  super "installing into parent path %s of %s is not allowed" %
          [destination, destination_dir]
end


class Gem::Package::TarHeader - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::TarHeader

A header for a tar file

In Files

  • lib/rubygems/package/tar_header.rb

Parent

Object

Constants

FIELDS

Fields in the tar header

PACK_FORMAT

Pack format for a tar header

UNPACK_FORMAT

Unpack format for a tar header

Public Class Methods

from(stream) click to toggle source

Creates a tar header from IO stream

# File lib/rubygems/package/tar_header.rb, line 98
def self.from(stream)
  header = stream.read 512
  empty = (header == "\00"" * 512)

  fields = header.unpack UNPACK_FORMAT

  new :name     => fields.shift,
      :mode     => fields.shift.oct,
      :uid      => fields.shift.oct,
      :gid      => fields.shift.oct,
      :size     => fields.shift.oct,
      :mtime    => fields.shift.oct,
      :checksum => fields.shift.oct,
      :typeflag => fields.shift,
      :linkname => fields.shift,
      :magic    => fields.shift,
      :version  => fields.shift.oct,
      :uname    => fields.shift,
      :gname    => fields.shift,
      :devmajor => fields.shift.oct,
      :devminor => fields.shift.oct,
      :prefix   => fields.shift,

      :empty => empty
end
new(vals) click to toggle source

Creates a new TarHeader using vals

# File lib/rubygems/package/tar_header.rb, line 127
def initialize(vals)
  unless vals[:name] && vals[:size] && vals[:prefix] && vals[:mode] then
    raise ArgumentError, ":name, :size, :prefix and :mode required"
  end

  vals[:uid] ||= 0
  vals[:gid] ||= 0
  vals[:mtime] ||= 0
  vals[:checksum] ||= ""
  vals[:typeflag] ||= "0"
  vals[:magic] ||= "ustar"
  vals[:version] ||= "00"
  vals[:uname] ||= "wheel"
  vals[:gname] ||= "wheel"
  vals[:devmajor] ||= 0
  vals[:devminor] ||= 0

  FIELDS.each do |name|
    instance_variable_set "@#{name}", vals[name]
  end

  @empty = vals[:empty]
end

Public Instance Methods

empty?() click to toggle source

Is the tar entry empty?

# File lib/rubygems/package/tar_header.rb, line 154
def empty?
  @empty
end
update_checksum() click to toggle source

Updates the TarHeader's checksum

# File lib/rubygems/package/tar_header.rb, line 186
def update_checksum
  header = header " " * 8
  @checksum = oct calculate_checksum(header), 6
end


class Gem::Package::TarInvalidError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::TarInvalidError

Raised when a tar file is corrupt

In Files

  • lib/rubygems/package.rb

Parent

Gem::Package::Error


class Gem::Package::TarReader - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::TarReader

TarReader reads tar files and allows iteration over their items

In Files

  • lib/rubygems/package/tar_reader.rb

Parent

Object

Included Modules

  • Enumerable

Public Class Methods

new(io) { |reader| ... } click to toggle source

Creates a new TarReader on io and yields it to the block, if given.

# File lib/rubygems/package/tar_reader.rb, line 21
def self.new(io)
  reader = super

  return reader unless block_given?

  begin
    yield reader
  ensure
    reader.close
  end

  nil
end
new(io) click to toggle source

Creates a new tar file reader on io which needs to respond to pos, eof?, read, getc and pos=

# File lib/rubygems/package/tar_reader.rb, line 39
def initialize(io)
  @io = io
  @init_pos = io.pos
end

Public Instance Methods

close() click to toggle source

Close the tar file

# File lib/rubygems/package/tar_reader.rb, line 47
def close
end
each() { |entry| ... } click to toggle source

Iterates over files in the tarball yielding each entry

# File lib/rubygems/package/tar_reader.rb, line 53
def each
  return enum_for __method__ unless block_given?

  until @io.eof? do
    header = Gem::Package::TarHeader.from @io
    return if header.empty?

    entry = Gem::Package::TarReader::Entry.new header, @io
    size = entry.header.size

    yield entry

    skip = (512 - (size % 512)) % 512
    pending = size - entry.bytes_read

    begin
      # avoid reading...
      @io.seek pending, IO::SEEK_CUR
      pending = 0
    rescue Errno::EINVAL, NameError
      while pending > 0 do
        bytes_read = @io.read([pending, 4096].min).size
        raise UnexpectedEOF if @io.eof?
        pending -= bytes_read
      end
    end

    @io.read skip # discard trailing zeros

    # make sure nobody can use #read, #getc or #rewind anymore
    entry.close
  end
end
Also aliased as: each_entry
each_entry() click to toggle source
Alias for: each
rewind() click to toggle source

NOTE: Do not call rewind during each

# File lib/rubygems/package/tar_reader.rb, line 92
def rewind
  if @init_pos == 0 then
    raise Gem::Package::NonSeekableIO unless @io.respond_to? :rewind
    @io.rewind
  else
    raise Gem::Package::NonSeekableIO unless @io.respond_to? :pos=
    @io.pos = @init_pos
  end
end
seek(name) { |entry| ... } click to toggle source

Seeks through the tar file until it finds the entry with name and yields it. Rewinds the tar file to the beginning when the block terminates.

# File lib/rubygems/package/tar_reader.rb, line 107
def seek name # :yields: entry
  found = find do |entry|
    entry.full_name == name
  end

  return unless found

  return yield found
ensure
  rewind
end


class Gem::Package::TarReader::Entry - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::TarReader::Entry

Class for reading entries out of a tar file

In Files

  • lib/rubygems/package/tar_reader/entry.rb

Parent

Object

Attributes

header[R]

Header for this tar entry

Public Class Methods

new(header, io) click to toggle source

Creates a new tar entry for header that will be read from io

# File lib/rubygems/package/tar_reader/entry.rb, line 19
def initialize(header, io)
  @closed = false
  @header = header
  @io = io
  @orig_pos = @io.pos
  @read = 0
end

Public Instance Methods

bytes_read() click to toggle source

Number of bytes read out of the tar entry

# File lib/rubygems/package/tar_reader/entry.rb, line 34
def bytes_read
  @read
end
close() click to toggle source

Closes the tar entry

# File lib/rubygems/package/tar_reader/entry.rb, line 41
def close
  @closed = true
end
closed?() click to toggle source

Is the tar entry closed?

# File lib/rubygems/package/tar_reader/entry.rb, line 48
def closed?
  @closed
end
directory?() click to toggle source

Is this tar entry a directory?

# File lib/rubygems/package/tar_reader/entry.rb, line 93
def directory?
  @header.typeflag == "5"
end
eof?() click to toggle source

Are we at the end of the tar entry?

# File lib/rubygems/package/tar_reader/entry.rb, line 55
def eof?
  check_closed

  @read >= @header.size
end
file?() click to toggle source

Is this tar entry a file?

# File lib/rubygems/package/tar_reader/entry.rb, line 100
def file?
  @header.typeflag == "0"
end
full_name() click to toggle source

Full name of the tar entry

# File lib/rubygems/package/tar_reader/entry.rb, line 64
def full_name
  if @header.prefix != "" then
    File.join @header.prefix, @header.name
  else
    @header.name
  end
rescue ArgumentError => e
  raise unless e.message == 'string contains null byte'
  raise Gem::Package::TarInvalidError,
        'tar is corrupt, name contains null byte'
end
getc() click to toggle source

Read one byte from the tar entry

# File lib/rubygems/package/tar_reader/entry.rb, line 79
def getc
  check_closed

  return nil if @read >= @header.size

  ret = @io.getc
  @read += 1 if ret

  ret
end
pos() click to toggle source

The position in the tar entry

# File lib/rubygems/package/tar_reader/entry.rb, line 107
def pos
  check_closed

  bytes_read
end
read(len = nil) click to toggle source

Reads len bytes from the tar file entry, or the rest of the entry if nil

# File lib/rubygems/package/tar_reader/entry.rb, line 117
def read(len = nil)
  check_closed

  return nil if @read >= @header.size

  len ||= @header.size - @read
  max_read = [len, @header.size - @read].min

  ret = @io.read max_read
  @read += ret.size

  ret
end
rewind() click to toggle source

Rewinds to the beginning of the tar file entry

# File lib/rubygems/package/tar_reader/entry.rb, line 134
def rewind
  check_closed

  raise Gem::Package::NonSeekableIO unless @io.respond_to? :pos=

  @io.pos = @orig_pos
  @read = 0
end


class Gem::Package::TarReader::UnexpectedEOF - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::TarReader::UnexpectedEOF

Raised if the tar IO is not seekable

In Files

  • lib/rubygems/package/tar_reader.rb

Parent

StandardError


class Gem::Package::TarTestCase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::TarTestCase

A test case for Gem::Package::Tar* classes

In Files

  • lib/rubygems/package/tar_test_case.rb

Parent

Gem::TestCase

Public Instance Methods

ASCIIZ(str, length) click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 9
def ASCIIZ(str, length)
  str + "\00"" * (length - str.length)
end
SP(s) click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 13
def SP(s)
  s + " "
end
SP_Z(s) click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 17
def SP_Z(s)
  s + " \00""
end
Z(s) click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 21
def Z(s)
  s + "\00""
end
assert_headers_equal(expected, actual) click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 25
def assert_headers_equal(expected, actual)
  expected = expected.to_s unless String === expected
  actual = actual.to_s unless String === actual

  fields = %w[
    name 100
    mode 8
    uid 8
    gid 8
    size 12
    mtime 12
    checksum 8
    typeflag 1
    linkname 100
    magic 6
    version 2
    uname 32
    gname 32
    devmajor 8
    devminor 8
    prefix 155
  ]

  offset = 0

  until fields.empty? do
    name = fields.shift
    length = fields.shift.to_i

    if name == "checksum" then
      chksum_off = offset
      offset += length
      next
    end

    assert_equal expected[offset, length], actual[offset, length],
                 "Field #{name} of the tar header differs."

    offset += length
  end

  assert_equal expected[chksum_off, 8], actual[chksum_off, 8]
end
calc_checksum(header) click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 69
def calc_checksum(header)
  sum = header.unpack("C*").inject{|s,a| s + a}
  SP(Z(to_oct(sum, 6)))
end
header(type, fname, dname, length, mode, checksum = nil) click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 74
def header(type, fname, dname, length, mode, checksum = nil)
  checksum ||= " " * 8

  arr = [                  # struct tarfile_entry_posix
    ASCIIZ(fname, 100),    # char name[100];     ASCII + (Z unless filled)
    Z(to_oct(mode, 7)),    # char mode[8];       0 padded, octal null
    Z(to_oct(0, 7)),       # char uid[8];        ditto
    Z(to_oct(0, 7)),       # char gid[8];        ditto
    Z(to_oct(length, 11)), # char size[12];      0 padded, octal, null
    Z(to_oct(0, 11)),      # char mtime[12];     0 padded, octal, null
    checksum,              # char checksum[8];   0 padded, octal, null, space
    type,                  # char typeflag[1];   file: "0"  dir: "5"
    "\00"" * 100,            # char linkname[100]; ASCII + (Z unless filled)
    "ustar\00"",             # char magic[6];      "ustar\0"
    "00",                  # char version[2];    "00"
    ASCIIZ("wheel", 32),   # char uname[32];     ASCIIZ
    ASCIIZ("wheel", 32),   # char gname[32];     ASCIIZ
    Z(to_oct(0, 7)),       # char devmajor[8];   0 padded, octal, null
    Z(to_oct(0, 7)),       # char devminor[8];   0 padded, octal, null
    ASCIIZ(dname, 155)     # char prefix[155];   ASCII + (Z unless filled)
  ]

  format = "C100C8C8C8C12C12C8CC100C6C2C32C32C8C8C155"
  h = if RUBY_VERSION >= "1.9" then
        arr.join
      else
        arr = arr.join("").split(//).map{|x| x[0]}
        arr.pack format
      end
  ret = h + "\00"" * (512 - h.size)
  assert_equal(512, ret.size)
  ret
end
tar_dir_header(name, prefix, mode) click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 108
def tar_dir_header(name, prefix, mode)
  h = header("5", name, prefix, 0, mode)
  checksum = calc_checksum(h)
  header("5", name, prefix, 0, mode, checksum)
end
tar_file_header(fname, dname, mode, length) click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 114
def tar_file_header(fname, dname, mode, length)
  h = header("0", fname, dname, length, mode)
  checksum = calc_checksum(h)
  header("0", fname, dname, length, mode, checksum)
end
to_oct(n, pad_size) click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 120
def to_oct(n, pad_size)
  "%0#{pad_size}o" % n
end
util_dir_entry() click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 132
def util_dir_entry
  util_entry tar_dir_header("foo", "bar", 0)
end
util_entry(tar) click to toggle source
# File lib/rubygems/package/tar_test_case.rb, line 124
def util_entry(tar)
  io = TempIO.new tar

  header = Gem::Package::TarHeader.from io

  Gem::Package::TarReader::Entry.new header, io
end


class Gem::Package::TarWriter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::TarWriter

Allows writing of tar files

In Files

  • lib/rubygems/package/tar_writer.rb

Parent

Object

Public Class Methods

new(io) { |writer| ... } click to toggle source

Creates a new TarWriter, yielding it if a block is given

# File lib/rubygems/package/tar_writer.rb, line 76
def self.new(io)
  writer = super

  return writer unless block_given?

  begin
    yield writer
  ensure
    writer.close
  end

  nil
end
new(io) click to toggle source

Creates a new TarWriter that will write to io

# File lib/rubygems/package/tar_writer.rb, line 93
def initialize(io)
  @io = io
  @closed = false
end

Public Instance Methods

add_file(name, mode) { |io| ... } click to toggle source

Adds file name with permissions mode, and yields an IO for writing the file to

# File lib/rubygems/package/tar_writer.rb, line 102
def add_file(name, mode) # :yields: io
  check_closed

  raise Gem::Package::NonSeekableIO unless @io.respond_to? :pos=

  name, prefix = split_name name

  init_pos = @io.pos
  @io.write "\00"" * 512 # placeholder for the header

  yield RestrictedStream.new(@io) if block_given?

  size = @io.pos - init_pos - 512

  remainder = (512 - (size % 512)) % 512
  @io.write "\00"" * remainder

  final_pos = @io.pos
  @io.pos = init_pos

  header = Gem::Package::TarHeader.new :name => name, :mode => mode,
                                       :size => size, :prefix => prefix

  @io.write header
  @io.pos = final_pos

  self
end
add_file_digest(name, mode, digest_algorithms) { |io| ... } click to toggle source

Adds name with permissions mode to the tar, yielding io for writing the file. The digest_algorithm is written to a read-only name.sum file following the given file contents containing the digest name and hexdigest separated by a tab.

The created digest object is returned.

# File lib/rubygems/package/tar_writer.rb, line 139
def add_file_digest name, mode, digest_algorithms # :yields: io
  digests = digest_algorithms.map do |digest_algorithm|
    digest = digest_algorithm.new
    [digest.name, digest]
  end

  digests = Hash[*digests.flatten]

  add_file name, mode do |io|
    Gem::Package::DigestIO.wrap io, digests do |digest_io|
      yield digest_io
    end
  end

  digests
end
add_file_signed(name, mode, signer) { |io| ... } click to toggle source

Adds name with permissions mode to the tar, yielding io for writing the file. The signer is used to add a digest file using its digest_algorithm per #add_file_digest and a cryptographic signature in name.sig. If the signer has no key only the checksum file is added.

Returns the digest.

# File lib/rubygems/package/tar_writer.rb, line 164
def add_file_signed name, mode, signer
  digest_algorithms = [
    signer.digest_algorithm,
    OpenSSL::Digest::SHA512,
  ].uniq

  digests = add_file_digest name, mode, digest_algorithms do |io|
    yield io
  end

  signature_digest = digests.values.find do |digest|
    digest.name == signer.digest_name
  end

  signature = signer.sign signature_digest.digest

  add_file_simple "#{name}.sig", 0444, signature.length do |io|
    io.write signature
  end if signature

  digests
end
add_file_simple(name, mode, size) { |io| ... } click to toggle source

Add file name with permissions mode size bytes long. Yields an IO to write the file to.

# File lib/rubygems/package/tar_writer.rb, line 191
def add_file_simple(name, mode, size) # :yields: io
  check_closed

  name, prefix = split_name name

  header = Gem::Package::TarHeader.new(:name => name, :mode => mode,
                                       :size => size, :prefix => prefix).to_s

  @io.write header
  os = BoundedStream.new @io, size

  yield os if block_given?

  min_padding = size - os.written
  @io.write("\00"" * min_padding)

  remainder = (512 - (size % 512)) % 512
  @io.write("\00"" * remainder)

  self
end
check_closed() click to toggle source

Raises IOError if the TarWriter is closed

# File lib/rubygems/package/tar_writer.rb, line 216
def check_closed
  raise IOError, "closed #{self.class}" if closed?
end
close() click to toggle source

Closes the TarWriter

# File lib/rubygems/package/tar_writer.rb, line 223
def close
  check_closed

  @io.write "\00"" * 1024
  flush

  @closed = true
end
closed?() click to toggle source

Is the TarWriter closed?

# File lib/rubygems/package/tar_writer.rb, line 235
def closed?
  @closed
end
flush() click to toggle source

Flushes the TarWriter's IO

# File lib/rubygems/package/tar_writer.rb, line 242
def flush
  check_closed

  @io.flush if @io.respond_to? :flush
end
mkdir(name, mode) click to toggle source

Creates a new directory in the tar file name with mode

# File lib/rubygems/package/tar_writer.rb, line 251
def mkdir(name, mode)
  check_closed

  name, prefix = split_name(name)

  header = Gem::Package::TarHeader.new :name => name, :mode => mode,
                                       :typeflag => "5", :size => 0,
                                       :prefix => prefix

  @io.write header

  self
end


class Gem::Package::TarWriter::BoundedStream - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::TarWriter::BoundedStream

IO wrapper that allows writing a limited amount of data

In Files

  • lib/rubygems/package/tar_writer.rb

Parent

Object

Attributes

limit[R]

Maximum number of bytes that can be written

written[R]

Number of bytes written

Public Class Methods

new(io, limit) click to toggle source

Wraps io and allows up to limit bytes to be written

# File lib/rubygems/package/tar_writer.rb, line 31
def initialize(io, limit)
  @io = io
  @limit = limit
  @written = 0
end

Public Instance Methods

write(data) click to toggle source

Writes data onto the IO, raising a FileOverflow exception if the number of bytes will be more than limit

# File lib/rubygems/package/tar_writer.rb, line 41
def write(data)
  if data.bytesize + @written > @limit
    raise FileOverflow, "You tried to feed more data than fits in the file."
  end
  @io.write data
  @written += data.bytesize
  data.bytesize
end


class Gem::Package::TarWriter::FileOverflow - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::TarWriter::FileOverflow

In Files

  • lib/rubygems/package/tar_writer.rb

Parent

StandardError


class Gem::Package::TarWriter::RestrictedStream - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::TarWriter::RestrictedStream

IO wrapper that provides only write

In Files

  • lib/rubygems/package/tar_writer.rb

Parent

Object

Public Class Methods

new(io) click to toggle source

Creates a new RestrictedStream wrapping io

# File lib/rubygems/package/tar_writer.rb, line 60
def initialize(io)
  @io = io
end

Public Instance Methods

write(data) click to toggle source

Writes data onto the IO

# File lib/rubygems/package/tar_writer.rb, line 67
def write(data)
  @io.write data
end


class Gem::Package::TooLongFileName - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Package::TooLongFileName

In Files

  • lib/rubygems/package.rb

Parent

Gem::Package::Error


class Gem::PackageTask - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::PackageTask

Create a package based upon a Gem::Specification. Gem packages, as well as zip files and tar/gzipped packages can be produced by this task.

In addition to the Rake targets generated by Rake::PackageTask, a Gem::PackageTask will also generate the following tasks:

“package_dir/name-version.gem”

Create a RubyGems package with the given name and version.

Example using a Gem::Specification:

require 'rubygems'
require 'rubygems/package_task'

spec = Gem::Specification.new do |s|
  s.summary = "Ruby based make-like utility."
  s.name = 'rake'
  s.version = PKG_VERSION
  s.requirements << 'none'
  s.files = PKG_FILES
  s.description = <<-EOF
Rake is a Make-like program implemented in Ruby. Tasks
and dependencies are specified in standard Ruby syntax.
  EOF
end

Gem::PackageTask.new(spec) do |pkg|
  pkg.need_zip = true
  pkg.need_tar = true
end

In Files

  • lib/rubygems/package_task.rb

Parent

Rake::PackageTask

Attributes

gem_spec[RW]

Ruby Gem::Specification containing the metadata for this package. The name, version and package_files are automatically determined from the gemspec and don't need to be explicitly provided.

Public Class Methods

new(gem_spec) { |self| ... } click to toggle source

Create a Gem Package task library. Automatically define the gem if a block is given. If no block is supplied, then define needs to be called to define the task.

# File lib/rubygems/package_task.rb, line 77
def initialize(gem_spec)
  init gem_spec
  yield self if block_given?
  define if block_given?
end

Public Instance Methods

define() click to toggle source

Create the Rake tasks and actions specified by this Gem::PackageTask. (define is automatically called if a block is given to new).

# File lib/rubygems/package_task.rb, line 96
def define
  super

  gem_file = File.basename gem_spec.cache_file
  gem_path = File.join package_dir, gem_file
  gem_dir  = File.join package_dir, gem_spec.full_name

  task :package => [:gem]

  directory package_dir
  directory gem_dir

  desc "Build the gem file #{gem_file}"
  task :gem => [gem_path]

  trace = Rake.application.options.trace
  Gem.configuration.verbose = trace

  file gem_path => [package_dir, gem_dir] + @gem_spec.files do
    chdir(gem_dir) do
      when_writing "Creating #{gem_spec.file_name}" do
        Gem::Package.build gem_spec

        verbose trace do
          mv gem_file, '..'
        end
      end
    end
  end
end
init(gem) click to toggle source

Initialization tasks without the “yield self” or define operations.

# File lib/rubygems/package_task.rb, line 86
def init(gem)
  super gem.full_name, :noversion
  @gem_spec = gem
  @package_files += gem_spec.files if gem_spec.files
end


class Gem::PathSupport - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::PathSupport

Gem::PathSupport facilitates the GEM_HOME and GEM_PATH environment settings to the rest of RubyGems.

In Files

  • lib/rubygems/path_support.rb

Parent

Object

Attributes

home[R]

The default system path for managing Gems.

path[R]

Array of paths to search for Gems.

Public Class Methods

new(env=ENV) click to toggle source

Constructor. Takes a single argument which is to be treated like a hashtable, or defaults to ENV, the system environment.

# File lib/rubygems/path_support.rb, line 20
def initialize(env=ENV)
  @env = env

  # note 'env' vs 'ENV'...
  @home     = env["GEM_HOME"] || ENV["GEM_HOME"] || Gem.default_dir

  if File::ALT_SEPARATOR then
    @home   = @home.gsub(File::ALT_SEPARATOR, File::SEPARATOR)
  end

  self.path = env["GEM_PATH"] || ENV["GEM_PATH"]
end


class Gem::Platform - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Platform

Available list of platforms for targeting Gem installations.

In Files

  • lib/rubygems/platform.rb

Parent

Object

Constants

CURRENT

A platform-specific gem that is built for the packaging ruby's platform. This will be replaced with ::local.

RUBY

A pure-ruby gem that may use Gem::Specification#extensions to build binary files.

Attributes

cpu[RW]
os[RW]
version[RW]

Public Class Methods

local() click to toggle source
# File lib/rubygems/platform.rb, line 16
def self.local
  arch = Gem::ConfigMap[:arch]
  arch = "#{arch}_60" if arch =~ /mswin32$/
  @local ||= new(arch)
end
match(platform) click to toggle source
# File lib/rubygems/platform.rb, line 22
def self.match(platform)
  Gem.platforms.any? do |local_platform|
    platform.nil? or
      local_platform == platform or
      (local_platform != Gem::Platform::RUBY and local_platform =~ platform)
  end
end
new(arch) click to toggle source
# File lib/rubygems/platform.rb, line 41
def initialize(arch)
  case arch
  when Array then
    @cpu, @os, @version = arch
  when String then
    arch = arch.split '-'

    if arch.length > 2 and arch.last !~ /\d/ then # reassemble x86-linux-gnu
      extra = arch.pop
      arch.last << "-#{extra}"
    end

    cpu = arch.shift

    @cpu = case cpu
           when /i\d86/ then 'x86'
           else cpu
           end

    if arch.length == 2 and arch.last =~ /^\d+(\.\d+)?$/ then # for command-line
      @os, @version = arch
      return
    end

    os, = arch
    @cpu, os = nil, cpu if os.nil? # legacy jruby

    @os, @version = case os
                    when /aix(\d+)?/ then             [ 'aix',       $1  ]
                    when /cygwin/ then                [ 'cygwin',    nil ]
                    when /darwin(\d+)?/ then          [ 'darwin',    $1  ]
                    when /^macruby$/ then             [ 'macruby',   nil ]
                    when /freebsd(\d+)?/ then         [ 'freebsd',   $1  ]
                    when /hpux(\d+)?/ then            [ 'hpux',      $1  ]
                    when /^java$/, /^jruby$/ then     [ 'java',      nil ]
                    when /^java([\d.]*)/ then         [ 'java',      $1  ]
                    when /^dalvik(\d+)?$/ then        [ 'dalvik',    $1  ]
                    when /^dotnet$/ then              [ 'dotnet',    nil ]
                    when /^dotnet([\d.]*)/ then       [ 'dotnet',    $1  ]
                    when /linux/ then                 [ 'linux',     $1  ]
                    when /mingw32/ then               [ 'mingw32',   nil ]
                    when /(mswin\d+)(\_(\d+))?/ then
                      os, version = $1, $3
                      @cpu = 'x86' if @cpu.nil? and os =~ /32$/
                      [os, version]
                    when /netbsdelf/ then             [ 'netbsdelf', nil ]
                    when /openbsd(\d+\.\d+)?/ then    [ 'openbsd',   $1  ]
                    when /solaris(\d+\.\d+)?/ then    [ 'solaris',   $1  ]
                    # test
                    when /^(\w+_platform)(\d+)?/ then [ $1,          $2  ]
                    else                              [ 'unknown',   nil ]
                    end
  when Gem::Platform then
    @cpu = arch.cpu
    @os = arch.os
    @version = arch.version
  else
    raise ArgumentError, "invalid argument #{arch.inspect}"
  end
end

Public Instance Methods

==(other) click to toggle source

Is other equal to this platform? Two platforms are equal if they have the same CPU, OS and version.

# File lib/rubygems/platform.rb, line 118
def ==(other)
  self.class === other and to_a == other.to_a
end
Also aliased as: eql?
===(other) click to toggle source

Does other match this platform? Two platforms match if they have the same CPU, or either has a CPU of 'universal', they have the same OS, and they have the same version, or either has no version.

# File lib/rubygems/platform.rb, line 133
def ===(other)
  return nil unless Gem::Platform === other

  # cpu
  (@cpu == 'universal' or other.cpu == 'universal' or @cpu == other.cpu) and

  # os
  @os == other.os and

  # version
  (@version.nil? or other.version.nil? or @version == other.version)
end
=~(other) click to toggle source

Does other match this platform? If other is a String it will be converted to a Gem::Platform first. See #=== for matching rules.

# File lib/rubygems/platform.rb, line 150
def =~(other)
  case other
  when Gem::Platform then # nop
  when String then
    # This data is from http://gems.rubyforge.org/gems/yaml on 19 Aug 2007
    other = case other
            when /^i686-darwin(\d)/     then ['x86',       'darwin',  $1    ]
            when /^i\d86-linux/         then ['x86',       'linux',   nil   ]
            when 'java', 'jruby'        then [nil,         'java',    nil   ]
            when /^dalvik(\d+)?$/       then [nil,         'dalvik',  $1    ]
            when /dotnet(\-(\d+\.\d+))?/ then ['universal','dotnet',  $2    ]
            when /mswin32(\_(\d+))?/    then ['x86',       'mswin32', $2    ]
            when 'powerpc-darwin'       then ['powerpc',   'darwin',  nil   ]
            when /powerpc-darwin(\d)/   then ['powerpc',   'darwin',  $1    ]
            when /sparc-solaris2.8/     then ['sparc',     'solaris', '2.8' ]
            when /universal-darwin(\d)/ then ['universal', 'darwin',  $1    ]
            else                             other
            end

    other = Gem::Platform.new other
  else
    return nil
  end

  self === other
end
eql?(other) click to toggle source
Alias for: ==
inspect() click to toggle source
# File lib/rubygems/platform.rb, line 102
def inspect
  "#<%s:0x%x @cpu=%p, @os=%p, @version=%p>" % [self.class, object_id, *to_a]
end
to_a() click to toggle source
# File lib/rubygems/platform.rb, line 106
def to_a
  [@cpu, @os, @version]
end
to_s() click to toggle source
# File lib/rubygems/platform.rb, line 110
def to_s
  to_a.compact.join '-'
end


class Gem::PlatformMismatch - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::PlatformMismatch

Generated when trying to lookup a gem to indicate that the gem was found, but that it isn't usable on the current platform.

fetch and install read these and report them to the user to aid in figuring out why a gem couldn't be installed.

In Files

  • lib/rubygems/errors.rb

Parent

Gem::ErrorReason

Attributes

name[R]

the name of the gem

platforms[R]

The platforms that are mismatched

version[R]

the version

Public Class Methods

new(name, version) click to toggle source
# File lib/rubygems/errors.rb, line 46
def initialize(name, version)
  @name = name
  @version = version
  @platforms = []
end

Public Instance Methods

add_platform(platform) click to toggle source

append a platform to the list of mismatched platforms.

Platforms are added via this instead of injected via the constructor so that we can loop over a list of mismatches and just add them rather than perform some kind of calculation mismatch summary before creation.

# File lib/rubygems/errors.rb, line 58
def add_platform(platform)
  @platforms << platform
end
wordy() click to toggle source

A wordy description of the error.

# File lib/rubygems/errors.rb, line 64
def wordy
  "Found %s (%s), but was for platform%s %s" %
    [@name,
     @version,
     @platforms.size == 1 ? '' : 's',
     @platforms.join(' ,')]
end


class Gem::RemoteError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::RemoteError

Signals that a remote operation cannot be conducted, probably due to not being connected (or just not finding host).

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::RemoteFetcher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::RemoteFetcher

RemoteFetcher handles the details of fetching gems and gem information from a remote source.

In Files

  • lib/rubygems/remote_fetcher.rb
  • lib/rubygems/test_utilities.rb

Parent

Object

Included Modules

  • Gem::UserInteraction

Public Class Methods

fetcher() click to toggle source

Cached RemoteFetcher instance.

# File lib/rubygems/remote_fetcher.rb, line 50
def self.fetcher
  @fetcher ||= self.new Gem.configuration[:http_proxy]
end
fetcher=(fetcher) click to toggle source
# File lib/rubygems/test_utilities.rb, line 155
def self.fetcher=(fetcher)
  @fetcher = fetcher
end
new(proxy=nil, dns=Resolv::DNS.new) click to toggle source

Initialize a remote fetcher using the source URI and possible proxy information.

proxy

  • [String]: explicit specification of proxy; overrides any environment

    variable setting

  • nil: respect environment variables (HTTP_PROXY, HTTP_PROXY_USER,

    HTTP_PROXY_PASS)

  • :no_proxy: ignore environment variables and _don't_ use a proxy

dns: An object to use for DNS resolution of the API endpoint.

By default, use Resolv::DNS.
# File lib/rubygems/remote_fetcher.rb, line 68
def initialize(proxy=nil, dns=Resolv::DNS.new)
  require 'net/http'
  require 'stringio'
  require 'time'
  require 'uri'

  Socket.do_not_reverse_lookup = true

  @connections = {}
  @connections_mutex = Mutex.new
  @requests = Hash.new 0
  @proxy_uri =
    case proxy
    when :no_proxy then nil
    when nil then get_proxy_from_env
    when URI::HTTP then proxy
    else URI.parse(proxy)
    end
  @user_agent = user_agent
  @env_no_proxy = get_no_proxy_from_env

  @dns = dns
end

Public Instance Methods

add_rubygems_trusted_certs(store) click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 448
def add_rubygems_trusted_certs(store)
  pattern = File.expand_path("./ssl_certs/*.pem", File.dirname(__FILE__))
  Dir.glob(pattern).each do |ssl_cert_file|
    store.add_file ssl_cert_file
  end
end
api_endpoint(uri) click to toggle source

Given a source at uri, calculate what hostname to actually connect to query the data for it.

# File lib/rubygems/remote_fetcher.rb, line 97
def api_endpoint(uri)
  host = uri.host

  begin
    res = @dns.getresource "_rubygems._tcp.#{host}",
                           Resolv::DNS::Resource::IN::SRV
  rescue Resolv::ResolvError
    uri
  else
    URI.parse "#{res.target}#{uri.path}"
  end
end
cache_update_path(uri, path = nil, update = true) click to toggle source

Downloads uri to path if necessary. If no path is given, it just passes the data.

# File lib/rubygems/remote_fetcher.rb, line 298
def cache_update_path uri, path = nil, update = true
  mtime = path && File.stat(path).mtime rescue nil

  if mtime && Net::HTTPNotModified === fetch_path(uri, mtime, true)
    Gem.read_binary(path)
  else
    data = fetch_path(uri)

    if update and path then
      open(path, 'wb') do |io|
        io.write data
      end
    end

    data
  end
end
configure_connection_for_https(connection) click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 423
def configure_connection_for_https(connection)
  require 'net/https'
  connection.use_ssl = true
  connection.verify_mode =
    Gem.configuration.ssl_verify_mode || OpenSSL::SSL::VERIFY_PEER
  store = OpenSSL::X509::Store.new
  if Gem.configuration.ssl_ca_cert
    if File.directory? Gem.configuration.ssl_ca_cert
      store.add_path Gem.configuration.ssl_ca_cert
    else
      store.add_file Gem.configuration.ssl_ca_cert
    end
  else
    store.set_default_paths
    add_rubygems_trusted_certs(store)
  end
  connection.cert_store = store
rescue LoadError => e
  raise unless (e.respond_to?(:path) && e.path == 'openssl') ||
               e.message =~ / -- openssl$/

  raise Gem::Exception.new(
          'Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non-HTTPS sources')
end
connection_for(uri) click to toggle source

Creates or an HTTP connection based on uri, or retrieves an existing connection, using a proxy if needed.

# File lib/rubygems/remote_fetcher.rb, line 392
def connection_for(uri)
  net_http_args = [uri.host, uri.port]

  if @proxy_uri and not no_proxy?(uri.host) then
    net_http_args += [
      @proxy_uri.host,
      @proxy_uri.port,
      unescape_auth_info(@proxy_uri.user),
      unescape_auth_info(@proxy_uri.password)
    ]
  end

  connection_id = [Thread.current.object_id, *net_http_args].join ':'

  connection = @connections_mutex.synchronize do
    @connections[connection_id] ||= Net::HTTP.new(*net_http_args)
    @connections[connection_id]
  end

  if https?(uri) and not connection.started? then
    configure_connection_for_https(connection)
  end

  connection.start unless connection.started?

  connection
rescue defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : Errno::EHOSTDOWN,
       Errno::EHOSTDOWN => e
  raise FetchError.new(e.message, uri)
end
correct_for_windows_path(path) click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 455
def correct_for_windows_path(path)
  if path[0].chr == '/' && path[1].chr =~ /[a-z]/ && path[2].chr == ':'
    path = path[1..-1]
  else
    path
  end
end
download(spec, source_uri, install_dir = Gem.dir) click to toggle source

Moves the gem spec from source_uri to the cache dir unless it is already there. If the source_uri is local the gem cache dir copy is always replaced.

# File lib/rubygems/remote_fetcher.rb, line 132
def download(spec, source_uri, install_dir = Gem.dir)
  cache_dir =
    if Dir.pwd == install_dir then # see fetch_command
      install_dir
    elsif File.writable? install_dir then
      File.join install_dir, "cache"
    else
      File.join Gem.user_dir, "cache"
    end

  gem_file_name = File.basename spec.cache_file
  local_gem_path = File.join cache_dir, gem_file_name

  FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir

 # Always escape URI's to deal with potential spaces and such
  unless URI::Generic === source_uri
    source_uri = URI.parse(URI.const_defined?(:DEFAULT_PARSER) ?
                           URI::DEFAULT_PARSER.escape(source_uri.to_s) :
                           URI.escape(source_uri.to_s))
  end

  scheme = source_uri.scheme

  # URI.parse gets confused by MS Windows paths with forward slashes.
  scheme = nil if scheme =~ /^[a-z]$/

  # REFACTOR: split this up and dispatch on scheme (eg download_http)
  # REFACTOR: be sure to clean up fake fetcher when you do this... cleaner
  case scheme
  when 'http', 'https' then
    unless File.exist? local_gem_path then
      begin
        say "Downloading gem #{gem_file_name}" if
          Gem.configuration.really_verbose

        remote_gem_path = source_uri + "gems/#{gem_file_name}"

        self.cache_update_path remote_gem_path, local_gem_path
      rescue Gem::RemoteFetcher::FetchError
        raise if spec.original_platform == spec.platform

        alternate_name = "#{spec.original_name}.gem"

        say "Failed, downloading gem #{alternate_name}" if
          Gem.configuration.really_verbose

        remote_gem_path = source_uri + "gems/#{alternate_name}"

        self.cache_update_path remote_gem_path, local_gem_path
      end
    end
  when 'file' then
    begin
      path = source_uri.path
      path = File.dirname(path) if File.extname(path) == '.gem'

      remote_gem_path = correct_for_windows_path(File.join(path, 'gems', gem_file_name))

      FileUtils.cp(remote_gem_path, local_gem_path)
    rescue Errno::EACCES
      local_gem_path = source_uri.to_s
    end

    say "Using local gem #{local_gem_path}" if
      Gem.configuration.really_verbose
  when nil then # TODO test for local overriding cache
    source_path = if Gem.win_platform? && source_uri.scheme &&
                     !source_uri.path.include?(':') then
                    "#{source_uri.scheme}:#{source_uri.path}"
                  else
                    source_uri.path
                  end

    source_path = unescape source_path

    begin
      FileUtils.cp source_path, local_gem_path unless
        File.identical?(source_path, local_gem_path)
    rescue Errno::EACCES
      local_gem_path = source_uri.to_s
    end

    say "Using local gem #{local_gem_path}" if
      Gem.configuration.really_verbose
  else
    raise ArgumentError, "unsupported URI scheme #{source_uri.scheme}"
  end

  local_gem_path
end
download_to_cache(dependency) click to toggle source

Given a name and requirement, downloads this gem into cache and returns the filename. Returns nil if the gem cannot be located.

# File lib/rubygems/remote_fetcher.rb, line 117
def download_to_cache dependency
  found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dependency

  return if found.empty?

  spec, source = found.sort_by { |(s,_)| s.version }.last

  download spec, source.uri.to_s
end
escape(str) click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 333
def escape(str)
  return unless str
  @uri_parser ||= uri_escaper
  @uri_parser.escape str
end
escape_auth_info(str) click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 325
def escape_auth_info(str)
  str && CGI.escape(str)
end
fetch_file(uri, *_) click to toggle source

File Fetcher. Dispatched by fetch_path. Use it instead.

# File lib/rubygems/remote_fetcher.rb, line 227
def fetch_file uri, *_
  Gem.read_binary correct_for_windows_path uri.path
end
fetch_http(uri, last_modified = nil, head = false, depth = 0) click to toggle source

HTTP Fetcher. Dispatched by fetch_path. Use it instead.

# File lib/rubygems/remote_fetcher.rb, line 234
def fetch_http uri, last_modified = nil, head = false, depth = 0
  fetch_type = head ? Net::HTTP::Head : Net::HTTP::Get
  response   = request uri, fetch_type, last_modified

  case response
  when Net::HTTPOK, Net::HTTPNotModified then
    head ? response : response.body
  when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
       Net::HTTPTemporaryRedirect then
    raise FetchError.new('too many redirects', uri) if depth > 10

    location = URI.parse response['Location']

    if https?(uri) && !https?(location)
      raise FetchError.new("redirecting to non-https resource: #{location}", uri)
    end

    fetch_http(location, last_modified, head, depth + 1)
  else
    raise FetchError.new("bad response #{response.message} #{response.code}", uri)
  end
end
Also aliased as: fetch_https
fetch_https(uri, last_modified = nil, head = false, depth = 0) click to toggle source
Alias for: fetch_http
fetch_path(uri, mtime = nil, head = false) click to toggle source

Downloads uri and returns it as a String.

# File lib/rubygems/remote_fetcher.rb, line 262
def fetch_path(uri, mtime = nil, head = false)
  uri = URI.parse uri unless URI::Generic === uri

  raise ArgumentError, "bad uri: #{uri}" unless uri

  unless uri.scheme
    raise ArgumentError, "uri scheme is invalid: #{uri.scheme.inspect}"
  end

  data = send "fetch_#{uri.scheme}", uri, mtime, head

  if data and !head and uri.to_s =~ /gz$/
    begin
      data = Gem.gunzip data
    rescue Zlib::GzipFile::Error
      raise FetchError.new("server did not return a valid file", uri.to_s)
    end
  end

  data
rescue FetchError
  raise
rescue Timeout::Error
  raise UnknownHostError.new('timed out', uri.to_s)
rescue IOError, SocketError, SystemCallError => e
  if e.message =~ /getaddrinfo/
    raise UnknownHostError.new('no such name', uri.to_s)
  else
    raise FetchError.new("#{e.class}: #{e}", uri.to_s)
  end
end
fetch_size(uri) click to toggle source

Returns the size of uri in bytes.

# File lib/rubygems/remote_fetcher.rb, line 319
def fetch_size(uri) # TODO: phase this out
  response = fetch_path(uri, nil, true)

  response['content-length'].to_i
end
get_no_proxy_from_env() click to toggle source

Returns list of no_proxy entries (if any) from the environment

# File lib/rubygems/remote_fetcher.rb, line 354
def get_no_proxy_from_env
  env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']

  return [] if env_no_proxy.nil?  or env_no_proxy.empty?

  env_no_proxy.split(/\s*,\s*/)
end
get_proxy_from_env() click to toggle source

Returns an HTTP proxy URI if one is set in the environment variables.

# File lib/rubygems/remote_fetcher.rb, line 365
def get_proxy_from_env
  env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']

  return nil if env_proxy.nil? or env_proxy.empty?

  uri = URI.parse(normalize_uri(env_proxy))

  if uri and uri.user.nil? and uri.password.nil? then
    # Probably we have http_proxy_* variables?
    uri.user = escape_auth_info(ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER'])
    uri.password = escape_auth_info(ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS'])
  end

  uri
end
https?(uri) click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 595
def https?(uri)
  uri.scheme.downcase == 'https'
end
no_proxy?(host) click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 463
def no_proxy? host
  host = host.downcase
  @env_no_proxy.each do |pattern|
    pattern = pattern.downcase
    return true if host[-pattern.length, pattern.length ] == pattern
  end
  return false
end
normalize_uri(uri) click to toggle source

Normalize the URI by adding “http://” if it is missing.

# File lib/rubygems/remote_fetcher.rb, line 384
def normalize_uri(uri)
  (uri =~ /^(https?|ftp|file):/) ? uri : "http://#{uri}"
end
request(uri, request_class, last_modified = nil) { |request| ... } click to toggle source

Performs a Net::HTTP request of type request_class on uri returning a Net::HTTP response object. request maintains a table of persistent connections to reduce connect overhead.

# File lib/rubygems/remote_fetcher.rb, line 477
def request(uri, request_class, last_modified = nil)
  request = request_class.new uri.request_uri

  unless uri.nil? || uri.user.nil? || uri.user.empty? then
    request.basic_auth uri.user, uri.password
  end

  request.add_field 'User-Agent', @user_agent
  request.add_field 'Connection', 'keep-alive'
  request.add_field 'Keep-Alive', '30'

  if last_modified then
    last_modified = last_modified.utc
    request.add_field 'If-Modified-Since', last_modified.rfc2822
  end

  yield request if block_given?

  connection = connection_for uri

  retried = false
  bad_response = false

  begin
    @requests[connection.object_id] += 1

    say "#{request.method} #{uri}" if
      Gem.configuration.really_verbose

    file_name = File.basename(uri.path)
    # perform download progress reporter only for gems
    if request.response_body_permitted? && file_name =~ /\.gem$/
      reporter = ui.download_reporter
      response = connection.request(request) do |incomplete_response|
        if Net::HTTPOK === incomplete_response
          reporter.fetch(file_name, incomplete_response.content_length)
          downloaded = 0
          data = ''

          incomplete_response.read_body do |segment|
            data << segment
            downloaded += segment.length
            reporter.update(downloaded)
          end
          reporter.done
          if incomplete_response.respond_to? :body=
            incomplete_response.body = data
          else
            incomplete_response.instance_variable_set(:@body, data)
          end
        end
      end
    else
      response = connection.request request
    end

    say "#{response.code} #{response.message}" if
      Gem.configuration.really_verbose

  rescue Net::HTTPBadResponse
    say "bad response" if Gem.configuration.really_verbose

    reset connection

    raise FetchError.new('too many bad responses', uri) if bad_response

    bad_response = true
    retry
  # HACK work around EOFError bug in Net::HTTP
  # NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
  # to install gems.
  rescue EOFError, Timeout::Error,
         Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE

    requests = @requests[connection.object_id]
    say "connection reset after #{requests} requests, retrying" if
      Gem.configuration.really_verbose

    raise FetchError.new('too many connection resets', uri) if retried

    reset connection

    retried = true
    retry
  end

  response
end
reset(connection) click to toggle source

Resets HTTP connection connection.

# File lib/rubygems/remote_fetcher.rb, line 569
def reset(connection)
  @requests.delete connection.object_id

  connection.finish
  connection.start
end
unescape(str) click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 339
def unescape(str)
  return unless str
  @uri_parser ||= uri_escaper
  @uri_parser.unescape str
end
unescape_auth_info(str) click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 329
def unescape_auth_info(str)
  str && CGI.unescape(str)
end
uri_escaper() click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 345
def uri_escaper
  URI::Parser.new
rescue NameError
  URI
end
user_agent() click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 576
def user_agent
  ua = "RubyGems/#{Gem::VERSION} #{Gem::Platform.local}"

  ruby_version = RUBY_VERSION
  ruby_version += 'dev' if RUBY_PATCHLEVEL == -1

  ua << " Ruby/#{ruby_version} (#{RUBY_RELEASE_DATE}"
  if RUBY_PATCHLEVEL >= 0 then
    ua << " patchlevel #{RUBY_PATCHLEVEL}"
  elsif defined?(RUBY_REVISION) then
    ua << " revision #{RUBY_REVISION}"
  end
  ua << ")"

  ua << " #{RUBY_ENGINE}" if defined?(RUBY_ENGINE) and RUBY_ENGINE != 'ruby'

  ua
end


class Gem::RemoteFetcher::FetchError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::RemoteFetcher::FetchError

A FetchError exception wraps up the various possible IO and HTTP failures that could happen while downloading from the internet.

In Files

  • lib/rubygems/remote_fetcher.rb

Parent

Gem::Exception

Attributes

uri[RW]

The URI which was being accessed when the exception happened.

Public Class Methods

new(message, uri) click to toggle source
# File lib/rubygems/remote_fetcher.rb, line 27
def initialize(message, uri)
  super message
  @uri = uri
end


class Gem::RemoteFetcher::UnknownHostError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::RemoteFetcher::UnknownHostError

A FetchError that indicates that the reason for not being able to fetch data was that the host could not be contacted

In Files

  • lib/rubygems/remote_fetcher.rb

Parent

Gem::RemoteFetcher::FetchError


class Gem::RemoteInstallationCancelled - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::RemoteInstallationCancelled

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::RemoteInstallationSkipped - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::RemoteInstallationSkipped

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::RemoteSourceException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::RemoteSourceException

Represents an error communicating via HTTP.

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::RequestSet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::RequestSet

In Files

  • lib/rubygems/request_set.rb

Parent

Object

Included Modules

  • TSort

Attributes

dependencies[R]

Public Class Methods

new(*deps) { |self| ... } click to toggle source
# File lib/rubygems/request_set.rb, line 13
def initialize(*deps)
  @dependencies = deps

  yield self if block_given?
end

Public Instance Methods

gem(name, *reqs) click to toggle source

Declare that a gem of name name with reqs requirements is needed.

# File lib/rubygems/request_set.rb, line 24
def gem(name, *reqs)
  @dependencies << Gem::Dependency.new(name, reqs)
end
import(deps) click to toggle source

Add deps Gem::Depedency objects to the set.

# File lib/rubygems/request_set.rb, line 30
def import(deps)
  @dependencies += deps
end
install(options, &b) click to toggle source
# File lib/rubygems/request_set.rb, line 119
def install(options, &b)
  if dir = options[:install_dir]
    return install_into(dir, false, &b)
  end

  cache_dir = options[:cache_dir] || Gem.dir

  specs = []

  sorted_requests.each do |req|
    if req.installed?
      b.call req, nil if b
      next
    end

    path = req.download cache_dir

    inst = Gem::Installer.new path, options

    b.call req, inst if b

    specs << inst.install
  end

  specs
end
install_into(dir, force=true, &b) click to toggle source
# File lib/rubygems/request_set.rb, line 91
def install_into(dir, force=true, &b)
  existing = force ? [] : specs_in(dir)

  dir = File.expand_path dir

  installed = []

  sorted_requests.each do |req|
    if existing.find { |s| s.full_name == req.spec.full_name }
      b.call req, nil if b
      next
    end

    path = req.download(dir)

    inst = Gem::Installer.new path, :install_dir => dir,
                                    :only_install_dir => true

    b.call req, inst if b

    inst.install

    installed << req
  end

  installed
end
load_gemdeps(path) click to toggle source

Load a dependency management file.

# File lib/rubygems/request_set.rb, line 52
def load_gemdeps(path)
  gf = GemDepedencyAPI.new(self, path)
  gf.load
end
resolve(set=nil) click to toggle source

Resolve the requested dependencies and return an Array of Specification objects to be activated.

# File lib/rubygems/request_set.rb, line 37
def resolve(set=nil)
  r = Gem::DependencyResolver.new(@dependencies, set)
  @requests = r.resolve
end
resolve_current() click to toggle source

Resolve the requested dependencies against the gems available via Gem.path and return an Array of Specification objects to be activated.

# File lib/rubygems/request_set.rb, line 46
def resolve_current
  resolve DependencyResolver::CurrentSet.new
end
sorted_requests() click to toggle source
# File lib/rubygems/request_set.rb, line 81
def sorted_requests
  @sorted ||= strongly_connected_components.flatten
end
specs() click to toggle source
# File lib/rubygems/request_set.rb, line 57
def specs
  @specs ||= @requests.map { |r| r.full_spec }
end
specs_in(dir) click to toggle source
# File lib/rubygems/request_set.rb, line 85
def specs_in(dir)
  Dir["#{dir}/specifications/*.gemspec"].map do |g|
    Gem::Specification.load g
  end
end
tsort_each_child(node) { |match| ... } click to toggle source
# File lib/rubygems/request_set.rb, line 65
def tsort_each_child(node)
  node.spec.dependencies.each do |dep|
    next if dep.type == :development

    match = @requests.find { |r| dep.match? r.spec.name, r.spec.version }
    if match
      begin
        yield match
      rescue TSort::Cyclic
      end
    else
      raise Gem::DependencyError, "Unresolved depedency found during sorting - #{dep}"
    end
  end
end
tsort_each_node(&block) click to toggle source
# File lib/rubygems/request_set.rb, line 61
def tsort_each_node(&block)
  @requests.each(&block)
end


class Gem::RequestSet::GemDepedencyAPI - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::RequestSet::GemDepedencyAPI

A semi-compatible DSL for Bundler's Gemfile format

In Files

  • lib/rubygems/request_set.rb

Parent

Object

Public Class Methods

new(set, path) click to toggle source
# File lib/rubygems/request_set.rb, line 149
def initialize(set, path)
  @set = set
  @path = path
end

Public Instance Methods

gem(name, *reqs) click to toggle source
# File lib/rubygems/request_set.rb, line 163
def gem(name, *reqs)
  # Ignore the opts for now.
  reqs.pop if reqs.last.kind_of?(Hash)

  @set.gem name, *reqs
end
group(*what) click to toggle source
# File lib/rubygems/request_set.rb, line 178
def group(*what)
end
load() click to toggle source
# File lib/rubygems/request_set.rb, line 154
def load
  instance_eval File.read(@path).untaint, @path, 1
end
platform(what) { || ... } click to toggle source
# File lib/rubygems/request_set.rb, line 170
def platform(what)
  if what == :ruby
    yield
  end
end
Also aliased as: platforms
platforms(what) click to toggle source
Alias for: platform
source(url) click to toggle source

DSL

# File lib/rubygems/request_set.rb, line 160
def source(url)
end


class Gem::Version::Requirement - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Version::Requirement

In Files

  • lib/rubygems/requirement.rb

Parent

Object

Constants

DefaultRequirement
PATTERN
PATTERN_RAW

Public Class Methods

create(input) click to toggle source

REFACTOR: There's no reason that this can't be unified with .new. .new is the standard Ruby factory method.

# File lib/rubygems/requirement.rb, line 47
def self.create input
  case input
  when Gem::Requirement then
    input
  when Gem::Version, Array then
    new input
  else
    if input.respond_to? :to_str then
      new [input.to_str]
    else
      default
    end
  end
end
default() click to toggle source

A default “version requirement” can surely only be '>= 0'.

# File lib/rubygems/requirement.rb, line 65
def self.default
  new '>= 0'
end
new(*requirements) click to toggle source

Constructs a requirement from requirements. Requirements can be Strings, Gem::Versions, or Arrays of those. nil and duplicate requirements are ignored. An empty set of requirements is the same as ">= 0".

# File lib/rubygems/requirement.rb, line 112
def initialize *requirements
  requirements = requirements.flatten
  requirements.compact!
  requirements.uniq!

  if requirements.empty?
    @requirements = [DefaultRequirement]
  else
    @requirements = requirements.map! { |r| self.class.parse r }
  end
end
parse(obj) click to toggle source

REFACTOR: Little two element arrays like this have no real semantic value. I'd love to see something like this: Constraint = Struct.new(:operator, :version); (or similar) and have a Requirement be a list of Constraints.

# File lib/rubygems/requirement.rb, line 86
def self.parse obj
  return ["=", obj] if Gem::Version === obj

  unless PATTERN =~ obj.to_s
    raise BadRequirementError, "Illformed requirement [#{obj.inspect}]"
  end

  if $1 == ">=" && $2 == "0"
    DefaultRequirement
  else
    [$1 || "=", Gem::Version.new($2)]
  end
end

Public Instance Methods

==(other) click to toggle source

DOC: this should probably be :nodoc'd

# File lib/rubygems/requirement.rb, line 218
def == other
  Gem::Requirement === other and to_s == other.to_s
end
===(version) click to toggle source
Alias for: satisfied_by?
=~(version) click to toggle source
Alias for: satisfied_by?
encode_with(coder) click to toggle source
# File lib/rubygems/requirement.rb, line 173
def encode_with(coder)
  coder.add 'requirements', @requirements
end
none?() click to toggle source

FIX: maybe this should be using default ?

# File lib/rubygems/requirement.rb, line 128
def none?
  if @requirements.size == 1
    @requirements[0] == DefaultRequirement
  else
    false
  end
end
prerelease?() click to toggle source

A requirement is a prerelease if any of the versions inside of it are prereleases

# File lib/rubygems/requirement.rb, line 181
def prerelease?
  requirements.any? { |r| r.last.prerelease? }
end
satisfied_by?(version) click to toggle source

True if version satisfies this Requirement.

# File lib/rubygems/requirement.rb, line 194
def satisfied_by? version
  raise ArgumentError, "Need a Gem::Version: #{version.inspect}" unless
    Gem::Version === version
  # #28965: syck has a bug with unquoted '=' YAML.loading as YAML::DefaultKey
  requirements.all? { |op, rv| (OPS[op] || OPS["="]).call version, rv }
end
Also aliased as: ===, =~
specific?() click to toggle source

True if the requirement will not always match the latest version.

# File lib/rubygems/requirement.rb, line 207
def specific?
  return true if @requirements.length > 1 # GIGO, > 1, > 2 is silly

  not %w[> >=].include? @requirements.first.first # grab the operator
end
to_yaml_properties() click to toggle source
# File lib/rubygems/requirement.rb, line 169
def to_yaml_properties
  ["@requirements"]
end


class Gem::Requirement::BadRequirementError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Requirement::BadRequirementError

In Files

  • lib/rubygems/requirement.rb

Parent

ArgumentError


module Gem::Security - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::Security

Signing gems

The Gem::Security implements cryptographic signatures for gems. The section below is a step-by-step guide to using signed gems and generating your own.

Walkthrough

Building your certificate

In order to start signing your gems, you'll need to build a private key and a self-signed certificate. Here's how:

# build a private key and certificate for yourself:
$ gem cert --build you@example.com

This could take anywhere from a few seconds to a minute or two, depending on the speed of your computer (public key algorithms aren't exactly the speediest crypto algorithms in the world). When it's finished, you'll see the files “gem-private_key.pem” and “gem-public_cert.pem” in the current directory.

First things first: Move both files to ~/.gem if you don't already have a key and certificate in that directory. Ensure the file permissions make the key unreadable by others (by default the file is saved securely).

Keep your private key hidden; if it's compromised, someone can sign packages as you (note: PKI has ways of mitigating the risk of stolen keys; more on that later).

Signing Gems

In RubyGems 2 and newer there is no extra work to sign a gem. RubyGems will automatically find your key and certificate in your home directory and use them to sign newly packaged gems.

If your certificate is not self-signed (signed by a third party) RubyGems will attempt to load the certificate chain from the trusted certificates. Use gem cert --add signing_cert.pem to add your signers as trusted certificates. See below for further information on certificate chains.

If you build your gem it will automatically be signed. If you peek inside your gem file, you'll see a couple of new files have been added:

$ tar tf your-gem-1.0.gem
metadata.gz
metadata.gz.sum
metadata.gz.sig # metadata signature
data.tar.gz
data.tar.gz.sum
data.tar.gz.sig # data signature

Manually signing gems

If you wish to store your key in a separate secure location you'll need to set your gems up for signing by hand. To do this, set the signing_key and cert_chain in the gemspec before packaging your gem:

s.signing_key = '/secure/path/to/gem-private_key.pem'
s.cert_chain = %w[/secure/path/to/gem-public_cert.pem]

When you package your gem with these options set RubyGems will automatically load your key and certificate from the secure paths.

Signed gems and security policies

Now let's verify the signature. Go ahead and install the gem, but add the following options: -P HighSecurity, like this:

# install the gem with using the security policy "HighSecurity"
$ sudo gem install your.gem -P HighSecurity

The -P option sets your security policy – we'll talk about that in just a minute. Eh, what's this?

$ gem install -P HighSecurity your-gem-1.0.gem
ERROR:  While executing gem ... (Gem::Security::Exception)
    root cert /CN=you/DC=example is not trusted

The culprit here is the security policy. RubyGems has several different security policies. Let's take a short break and go over the security policies. Here's a list of the available security policies, and a brief description of each one:

  • NoSecurity - Well, no security at all. Signed packages are treated like unsigned packages.

  • LowSecurity - Pretty much no security. If a package is signed then RubyGems will make sure the signature matches the signing certificate, and that the signing certificate hasn't expired, but that's it. A malicious user could easily circumvent this kind of security.

  • MediumSecurity - Better than LowSecurity and NoSecurity, but still fallible. Package contents are verified against the signing certificate, and the signing certificate is checked for validity, and checked against the rest of the certificate chain (if you don't know what a certificate chain is, stay tuned, we'll get to that). The biggest improvement over LowSecurity is that MediumSecurity won't install packages that are signed by untrusted sources. Unfortunately, MediumSecurity still isn't totally secure – a malicious user can still unpack the gem, strip the signatures, and distribute the gem unsigned.

  • HighSecurity - Here's the bugger that got us into this mess. The HighSecurity policy is identical to the MediumSecurity policy, except that it does not allow unsigned gems. A malicious user doesn't have a whole lot of options here; he can't modify the package contents without invalidating the signature, and he can't modify or remove signature or the signing certificate chain, or RubyGems will simply refuse to install the package. Oh well, maybe he'll have better luck causing problems for CPAN users instead :).

The reason RubyGems refused to install your shiny new signed gem was because it was from an untrusted source. Well, your code is infallible (naturally), so you need to add yourself as a trusted source:

# add trusted certificate
gem cert --add ~/.gem/gem-public_cert.pem

You've now added your public certificate as a trusted source. Now you can install packages signed by your private key without any hassle. Let's try the install command above again:

# install the gem with using the HighSecurity policy (and this time
# without any shenanigans)
$ gem install -P HighSecurity your-gem-1.0.gem
Successfully installed your-gem-1.0
1 gem installed

This time RubyGems will accept your signed package and begin installing.

While you're waiting for RubyGems to work it's magic, have a look at some of the other security commands by running gem help cert:

Options:
  -a, --add CERT                   Add a trusted certificate.
  -l, --list [FILTER]              List trusted certificates where the
                                   subject contains FILTER
  -r, --remove FILTER              Remove trusted certificates where the
                                   subject contains FILTER
  -b, --build EMAIL_ADDR           Build private key and self-signed
                                   certificate for EMAIL_ADDR
  -C, --certificate CERT           Signing certificate for --sign
  -K, --private-key KEY            Key for --sign or --build
  -s, --sign CERT                  Signs CERT with the key from -K
                                   and the certificate from -C

We've already covered the --build option, and the --add, --list, and --remove commands seem fairly straightforward; they allow you to add, list, and remove the certificates in your trusted certificate list. But what's with this --sign option?

Certificate chains

To answer that question, let's take a look at “certificate chains”, a concept I mentioned earlier. There are a couple of problems with self-signed certificates: first of all, self-signed certificates don't offer a whole lot of security. Sure, the certificate says Yukihiro Matsumoto, but how do I know it was actually generated and signed by matz himself unless he gave me the certificate in person?

The second problem is scalability. Sure, if there are 50 gem authors, then I have 50 trusted certificates, no problem. What if there are 500 gem authors? 1000? Having to constantly add new trusted certificates is a pain, and it actually makes the trust system less secure by encouraging RubyGems users to blindly trust new certificates.

Here's where certificate chains come in. A certificate chain establishes an arbitrarily long chain of trust between an issuing certificate and a child certificate. So instead of trusting certificates on a per-developer basis, we use the PKI concept of certificate chains to build a logical hierarchy of trust. Here's a hypothetical example of a trust hierarchy based (roughly) on geography:

                    --------------------------
                    | rubygems@rubygems.org |
                    --------------------------
                                |
              -----------------------------------
              |                                 |
  ----------------------------    -----------------------------
  |  seattlerb@seattlerb.org |    | dcrubyists@richkilmer.com |
  ----------------------------    -----------------------------
       |                |                 |             |
---------------   ----------------   -----------   --------------
|   drbrain   |   |   zenspider  |   | pabs@dc |   | tomcope@dc |
---------------   ----------------   -----------   --------------

Now, rather than having 4 trusted certificates (one for drbrain, zenspider, pabs@dc, and tomecope@dc), a user could actually get by with one certificate, the “rubygems@rubygems.org” certificate.

Here's how it works:

I install “rdoc-3.12.gem”, a package signed by “drbrain”. I've never heard of “drbrain”, but his certificate has a valid signature from the “seattlerb at seattle.rb.org” certificate, which in turn has a valid signature from the “rubygems@rubygems.org” certificate. Voila! At this point, it's much more reasonable for me to trust a package signed by “drbrain”, because I can establish a chain to “rubygems@rubygems.org”, which I do trust.

Signing certificates

The --sign option allows all this to happen. A developer creates their build certificate with the --build option, then has their certificate signed by taking it with them to their next regional Ruby meetup (in our hypothetical example), and it's signed there by the person holding the regional RubyGems signing certificate, which is signed at the next RubyConf by the holder of the top-level RubyGems certificate. At each point the issuer runs the same command:

# sign a certificate with the specified key and certificate
# (note that this modifies client_cert.pem!)
$ gem cert -K /mnt/floppy/issuer-priv_key.pem -C issuer-pub_cert.pem
   --sign client_cert.pem

Then the holder of issued certificate (in this case, your buddy “drbrain”), can start using this signed certificate to sign RubyGems. By the way, in order to let everyone else know about his new fancy signed certificate, “drbrain” would save his newly signed certificate as ~/.gem/gem-public_cert.pem

Obviously this RubyGems trust infrastructure doesn't exist yet. Also, in the “real world”, issuers actually generate the child certificate from a certificate request, rather than sign an existing certificate. And our hypothetical infrastructure is missing a certificate revocation system. These are that can be fixed in the future…

At this point you should know how to do all of these new and interesting things:

  • build a gem signing key and certificate

  • adjust your security policy

  • modify your trusted certificate list

  • sign a certificate

Manually verifying signatures

In case you don't trust RubyGems you can verify gem signatures manually:

  1. Fetch and unpack the gem

    gem fetch some_signed_gem
tar -xf some_signed_gem-1.0.gem

  2. Grab the public key from the gemspec

    gem spec some_signed_gem-1.0.gem cert_chain | \
  ruby -ryaml -e 'puts YAML.load_documents($stdin)' > public_key.crt

  3. Generate a SHA1 hash of the data.tar.gz

    openssl dgst -sha1 < data.tar.gz > my.hash

  4. Verify the signature

    openssl rsautl -verify -inkey public_key.crt -certin \
  -in data.tar.gz.sig > verified.hash

  5. Compare your hash to the verified hash

    diff -s verified.hash my.hash

  6. Repeat 5 and 6 with metadata.gz

OpenSSL Reference

The .pem files generated by –build and –sign are PEM files. Here's a couple of useful OpenSSL commands for manipulating them:

# convert a PEM format X509 certificate into DER format:
# (note: Windows .cer files are X509 certificates in DER format)
$ openssl x509 -in input.pem -outform der -out output.der

# print out the certificate in a human-readable format:
$ openssl x509 -in input.pem -noout -text

And you can do the same thing with the private key file as well:

# convert a PEM format RSA key into DER format:
$ openssl rsa -in input_key.pem -outform der -out output_key.der

# print out the key in a human readable format:
$ openssl rsa -in input_key.pem -noout -text

Bugs/TODO

  • There's no way to define a system-wide trust list.

  • custom security policies (from a YAML file, etc)

  • Simple method to generate a signed certificate request

  • Support for OCSP, SCVP, CRLs, or some other form of cert status check (list is in order of preference)

  • Support for encrypted private keys

  • Some sort of semi-formal trust hierarchy (see long-winded explanation above)

  • Path discovery (for gem certificate chains that don't have a self-signed root) – by the way, since we don't have this, THE ROOT OF THE CERTIFICATE CHAIN MUST BE SELF SIGNED if Gem::Security::Policy#verify_root is true (and it is for the MediumSecurity and HighSecurity policies)

  • Better explanation of X509 naming (ie, we don't have to use email addresses)

  • Honor AIA field (see note about OCSP above)

  • Honor extension restrictions

  • Might be better to store the certificate chain as a PKCS#7 or PKCS#12 file, instead of an array embedded in the metadata.

  • Flexible signature and key algorithms, not hard-coded to RSA and SHA1.

Original author

Paul Duncan <pabs@pablotron.org> pablotron.org/

In Files

  • lib/rubygems/install_update_options.rb
  • lib/rubygems/security/policies.rb
  • lib/rubygems/security.rb

Constants

AlmostNoSecurity

AlmostNo security policy: only verify that the signing certificate is the one that actually signed the data. Make no attempt to verify the signing certificate chain.

This policy is basically useless. better than nothing, but can still be easily spoofed, and is not recommended.

DIGEST_ALGORITHM

Digest algorithm used to sign gems

EXTENSIONS

The default set of extensions are:

  • The certificate is not a certificate authority

  • The key for the certificate may be used for key and data encipherment and digital signatures

  • The certificate contains a subject key identifier

HighSecurity

High security policy: only allow signed gems to be installed, verify the signing certificate, verify the signing certificate chain all the way to the root certificate, and only trust root certificates that we have explicitly allowed trust for.

This security policy is significantly more difficult to bypass, and offers a reasonable guarantee that the contents of the gem have not been altered.

KEY_ALGORITHM

Algorithm for creating the key pair used to sign gems

KEY_LENGTH

Length of keys created by KEY_ALGORITHM

LowSecurity

Low security policy: only verify that the signing certificate is actually the gem signer, and that the signing certificate is valid.

This policy is better than nothing, but can still be easily spoofed, and is not recommended.

MediumSecurity

Medium security policy: verify the signing certificate, verify the signing certificate chain all the way to the root certificate, and only trust root certificates that we have explicitly allowed trust for.

This security policy is reasonable, but it allows unsigned packages, so a malicious person could simply delete the package signature and pass the gem off as unsigned.

NoSecurity

No security policy: all package signature checks are disabled.

ONE_YEAR

One year in seconds

Policies

Hash of configured security policies

SigningPolicy

Policy used to verify a certificate and key when signing a gem

Public Class Methods

alt_name_or_x509_entry(certificate, x509_entry) click to toggle source
# File lib/rubygems/security.rb, line 392
def self.alt_name_or_x509_entry certificate, x509_entry
  alt_name = certificate.extensions.find do |extension|
    extension.oid == "#{x509_entry}AltName"
  end

  return alt_name.value if alt_name

  certificate.send x509_entry
end
create_cert(subject, key, age = ONE_YEAR, extensions = EXTENSIONS, serial = 1) click to toggle source

Creates an unsigned certificate for subject and key. The lifetime of the key is from the current time to age which defaults to one year.

The extensions restrict the key to the indicated uses.

# File lib/rubygems/security.rb, line 408
def self.create_cert subject, key, age = ONE_YEAR, extensions = EXTENSIONS,
                     serial = 1
  cert = OpenSSL::X509::Certificate.new

  cert.public_key = key.public_key
  cert.version    = 2
  cert.serial     = serial

  cert.not_before = Time.now
  cert.not_after  = Time.now + age

  cert.subject    = subject

  ef = OpenSSL::X509::ExtensionFactory.new nil, cert

  cert.extensions = extensions.map do |ext_name, value|
    ef.create_extension ext_name, value
  end

  cert
end
create_cert_email(email, key, age = ONE_YEAR, extensions = EXTENSIONS) click to toggle source

Creates a self-signed certificate with an issuer and subject from email, a subject alternative name of email and the given extensions for the key.

# File lib/rubygems/security.rb, line 435
def self.create_cert_email email, key, age = ONE_YEAR, extensions = EXTENSIONS
  subject = email_to_name email

  extensions = extensions.merge "subjectAltName" => "email:#{email}"

  create_cert_self_signed subject, key, age, extensions
end
create_cert_self_signed(subject, key, age = ONE_YEAR, extensions = EXTENSIONS, serial = 1) click to toggle source

Creates a self-signed certificate with an issuer and subject of subject and the given extensions for the key.

# File lib/rubygems/security.rb, line 447
def self.create_cert_self_signed subject, key, age = ONE_YEAR,
                                 extensions = EXTENSIONS, serial = 1
  certificate = create_cert subject, key, age, extensions

  sign certificate, key, certificate, age, extensions, serial
end
create_key(length = KEY_LENGTH, algorithm = KEY_ALGORITHM) click to toggle source

Creates a new key pair of the specified length and algorithm. The default is a 2048 bit RSA key.

# File lib/rubygems/security.rb, line 458
def self.create_key length = KEY_LENGTH, algorithm = KEY_ALGORITHM
  algorithm.new length
end
email_to_name(email_address) click to toggle source

Turns email_address into an OpenSSL::X509::Name

# File lib/rubygems/security.rb, line 465
def self.email_to_name email_address
  email_address = email_address.gsub(/[^\w@.-]+/, '_')

  cn, dcs = email_address.split '@'

  dcs = dcs.split '.'

  name = "CN=#{cn}/#{dcs.map { |dc| "DC=#{dc}" }.join '/'}"

  OpenSSL::X509::Name.parse name
end
re_sign(expired_certificate, private_key, age = ONE_YEAR, extensions = EXTENSIONS) click to toggle source

Signs expired_certificate with private_key if the keys match and the expired certificate was self-signed.

# File lib/rubygems/security.rb, line 483
def self.re_sign expired_certificate, private_key, age = ONE_YEAR,
                 extensions = EXTENSIONS
  raise Gem::Security::Exception,
        "incorrect signing key for re-signing " +
        "#{expired_certificate.subject}" unless
    expired_certificate.public_key.to_pem == private_key.public_key.to_pem

  unless expired_certificate.subject.to_s ==
         expired_certificate.issuer.to_s then
    subject = alt_name_or_x509_entry expired_certificate, :subject
    issuer  = alt_name_or_x509_entry expired_certificate, :issuer

    raise Gem::Security::Exception,
          "#{subject} is not self-signed, contact #{issuer} " +
          "to obtain a valid certificate"
  end

  serial = expired_certificate.serial + 1

  create_cert_self_signed(expired_certificate.subject, private_key, age,
                          extensions, serial)
end
reset() click to toggle source

Resets the trust directory for verifying gems.

# File lib/rubygems/security.rb, line 509
def self.reset
  @trust_dir = nil
end
sign(certificate, signing_key, signing_cert, age = ONE_YEAR, extensions = EXTENSIONS, serial = 1) click to toggle source

Sign the public key from certificate with the signing_key and signing_cert, using the Gem::Security::DIGEST_ALGORITHM. Uses the default certificate validity range and extensions.

Returns the newly signed certificate.

# File lib/rubygems/security.rb, line 520
def self.sign certificate, signing_key, signing_cert,
              age = ONE_YEAR, extensions = EXTENSIONS, serial = 1
  signee_subject = certificate.subject
  signee_key     = certificate.public_key

  alt_name = certificate.extensions.find do |extension|
    extension.oid == 'subjectAltName'
  end

  extensions = extensions.merge 'subjectAltName' => alt_name.value if
    alt_name

  issuer_alt_name = signing_cert.extensions.find do |extension|
    extension.oid == 'subjectAltName'
  end

  extensions = extensions.merge 'issuerAltName' => issuer_alt_name.value if
    issuer_alt_name

  signed = create_cert signee_subject, signee_key, age, extensions, serial
  signed.issuer = signing_cert.subject

  signed.sign signing_key, Gem::Security::DIGEST_ALGORITHM.new
end
trust_dir() click to toggle source

Returns a Gem::Security::TrustDir which wraps the directory where trusted certificates live.

# File lib/rubygems/security.rb, line 549
def self.trust_dir
  return @trust_dir if @trust_dir

  dir = File.join Gem.user_home, '.gem', 'trust'

  @trust_dir ||= Gem::Security::TrustDir.new dir
end
trusted_certificates(&block) click to toggle source

Enumerates the trusted certificates via Gem::Security::TrustDir.

# File lib/rubygems/security.rb, line 560
def self.trusted_certificates &block
  trust_dir.each_certificate(&block)
end
write(pemmable, path, permissions = 0600) click to toggle source

Writes pemmable, which must respond to to_pem to path with the given permissions.

# File lib/rubygems/security.rb, line 568
def self.write pemmable, path, permissions = 0600
  path = File.expand_path path

  open path, 'wb', permissions do |io|
    io.write pemmable.to_pem
  end

  path
end


class Gem::Security::DIGEST_ALGORITHM - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Security::DIGEST_ALGORITHM

In Files

  • lib/rubygems/security.rb

Parent

Object


class Gem::Security::Exception - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Security::Exception

Gem::Security default exception type

In Files

  • lib/rubygems/security.rb

Parent

Gem::Exception


class OpenSSL::PKey::RSA - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::RSA

RSA is an asymmetric public key algorithm that has been formalized in RFC 3447. It is in widespread use in public key infrastuctures (PKI) where certificates (cf. OpenSSL::X509::Certificate) often are issued on the basis of a public/private RSA key pair. RSA is used in a wide field of applications such as secure (symmetric) key exchange, e.g. when establishing a secure TLS/SSL connection. It is also used in various digital signature schemes.

In Files

  • lib/rubygems/security.rb
  • ext/openssl/ossl_pkey.c

Parent

cPKey

Public Class Methods

generate(size) → RSA instance click to toggle source
generate(size, exponent) → RSA instance

Generates an RSA keypair. size is an integer representing the desired key size. Keys smaller than 1024 should be considered insecure. exponent is an odd number normally 3, 17, or 65537.

static VALUE
ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)
{
/* why does this method exist?  why can't initialize take an optional exponent? */
    RSA *rsa;
    VALUE size, exp;
    VALUE obj;

    rb_scan_args(argc, argv, "11", &size, &exp);

    rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2ULONG(exp)); /* err handled by rsa_instance */
    obj = rsa_instance(klass, rsa);

    if (obj == Qfalse) {
        RSA_free(rsa);
        ossl_raise(eRSAError, NULL);
    }

    return obj;
}
new(key_size) → RSA instance click to toggle source
new(encoded_key) → RSA instance
new(encoded_key, pass_phrase) → RSA instance

Generates or loads an RSA keypair. If an integer key_size is given it represents the desired key size. Keys less than 1024 bits should be considered insecure.

A key can instead be loaded from an encoded_key which must be PEM or DER encoded. A pass_phrase can be used to decrypt the key. If none is given OpenSSL will prompt for the pass phrase.

Examples

OpenSSL::PKey::RSA.new 2048
OpenSSL::PKey::RSA.new File.read 'rsa.pem'
OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase'
static VALUE
ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    RSA *rsa;
    BIO *in;
    char *passwd = NULL;
    VALUE arg, pass;

    GetPKey(self, pkey);
    if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
        rsa = RSA_new();
    }
    else if (FIXNUM_P(arg)) {
        rsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2ULONG(pass));
        if (!rsa) ossl_raise(eRSAError, NULL);
    }
    else {
        if (!NIL_P(pass)) passwd = StringValuePtr(pass);
        arg = ossl_to_der_if_possible(arg);
        in = ossl_obj2bio(arg);
        rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
        if (!rsa) {
            OSSL_BIO_reset(in);
            rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
        }
        if (!rsa) {
            OSSL_BIO_reset(in);
            rsa = d2i_RSAPrivateKey_bio(in, NULL);
        }
        if (!rsa) {
            OSSL_BIO_reset(in);
            rsa = d2i_RSA_PUBKEY_bio(in, NULL);
        }
        if (!rsa) {
            OSSL_BIO_reset(in);
            rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
        }
        if (!rsa) {
            OSSL_BIO_reset(in);
            rsa = d2i_RSAPublicKey_bio(in, NULL);
        }
        BIO_free(in);
        if (!rsa) {
            ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
        }
    }
    if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
        RSA_free(rsa);
        ossl_raise(eRSAError, NULL);
    }

    return self;
}

Public Instance Methods

blinding_off!() click to toggle source
static VALUE
ossl_rsa_blinding_off(VALUE self)
{
    EVP_PKEY *pkey;

    GetPKeyRSA(self, pkey);
    RSA_blinding_off(pkey->pkey.rsa);

    return self;
}
blinding_on!() click to toggle source
static VALUE
ossl_rsa_blinding_on(VALUE self)
{
    EVP_PKEY *pkey;

    GetPKeyRSA(self, pkey);

    if (RSA_blinding_on(pkey->pkey.rsa, ossl_bn_ctx) != 1) {
        ossl_raise(eRSAError, NULL);
    }
    return self;
}
to_pem → PEM-format String click to toggle source
to_pem(cipher, pass_phrase) → PEM-format String

Outputs this keypair in PEM encoding. If cipher and pass_phrase are given they will be used to encrypt the key. cipher must be an OpenSSL::Cipher::Cipher instance.

static VALUE
ossl_rsa_export(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    BIO *out;
    const EVP_CIPHER *ciph = NULL;
    char *passwd = NULL;
    VALUE cipher, pass, str;

    GetPKeyRSA(self, pkey);

    rb_scan_args(argc, argv, "02", &cipher, &pass);

    if (!NIL_P(cipher)) {
        ciph = GetCipherPtr(cipher);
        if (!NIL_P(pass)) {
            StringValue(pass);
            if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
                ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
            passwd = RSTRING_PTR(pass);
        }
    }
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eRSAError, NULL);
    }
    if (RSA_HAS_PRIVATE(pkey->pkey.rsa)) {
        if (!PEM_write_bio_RSAPrivateKey(out, pkey->pkey.rsa, ciph,
                                         NULL, 0, ossl_pem_passwd_cb, passwd)) {
            BIO_free(out);
            ossl_raise(eRSAError, NULL);
        }
    } else {
        if (!PEM_write_bio_RSA_PUBKEY(out, pkey->pkey.rsa)) {
            BIO_free(out);
            ossl_raise(eRSAError, NULL);
        }
    }
    str = ossl_membio2str(out);

    return str;
}
Also aliased as: to_pem, to_s
params → hash click to toggle source

THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!

Stores all parameters of key to the hash. The hash has keys 'n', 'e', 'd', 'p', 'q', 'dmp1', 'dmq1', 'iqmp'.

Don't use :-)) (It's up to you)

static VALUE
ossl_rsa_get_params(VALUE self)
{
    EVP_PKEY *pkey;
    VALUE hash;

    GetPKeyRSA(self, pkey);

    hash = rb_hash_new();

    rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(pkey->pkey.rsa->n));
    rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(pkey->pkey.rsa->e));
    rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(pkey->pkey.rsa->d));
    rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.rsa->p));
    rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.rsa->q));
    rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(pkey->pkey.rsa->dmp1));
    rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(pkey->pkey.rsa->dmq1));
    rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(pkey->pkey.rsa->iqmp));

    return hash;
}
private? → true | false click to toggle source

Does this keypair contain a private key?

static VALUE
ossl_rsa_is_private(VALUE self)
{
    EVP_PKEY *pkey;

    GetPKeyRSA(self, pkey);

    return (RSA_PRIVATE(self, pkey->pkey.rsa)) ? Qtrue : Qfalse;
}
private_decrypt(string) → String click to toggle source
private_decrypt(string, padding) → String

Decrypt string, which has been encrypted with the public key, with the private key. padding defaults to PKCS1_PADDING.

static VALUE
ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    int buf_len, pad;
    VALUE str, buffer, padding;

    GetPKeyRSA(self, pkey);
    if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
        ossl_raise(eRSAError, "private key needed.");
    }
    rb_scan_args(argc, argv, "11", &buffer, &padding);
    pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
    StringValue(buffer);
    str = rb_str_new(0, ossl_rsa_buf_size(pkey));
    buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
                                  (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
                                  pad);
    if (buf_len < 0) ossl_raise(eRSAError, NULL);
    rb_str_set_len(str, buf_len);

    return str;
}
private_encrypt(string) → String click to toggle source
private_encrypt(string, padding) → String

Encrypt string with the private key. padding defaults to PKCS1_PADDING. The encrypted string output can be decrypted using public_decrypt.

static VALUE
ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    int buf_len, pad;
    VALUE str, buffer, padding;

    GetPKeyRSA(self, pkey);
    if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
        ossl_raise(eRSAError, "private key needed.");
    }
    rb_scan_args(argc, argv, "11", &buffer, &padding);
    pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
    StringValue(buffer);
    str = rb_str_new(0, ossl_rsa_buf_size(pkey));
    buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
                                  (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
                                  pad);
    if (buf_len < 0) ossl_raise(eRSAError, NULL);
    rb_str_set_len(str, buf_len);

    return str;
}
public? → true click to toggle source

The return value is always true since every private key is also a public key.

static VALUE
ossl_rsa_is_public(VALUE self)
{
    EVP_PKEY *pkey;

    GetPKeyRSA(self, pkey);
    /*
     * This method should check for n and e.  BUG.
     */
    return Qtrue;
}
public_decrypt(string) → String click to toggle source
public_decrypt(string, padding) → String

Decrypt string, which has been encrypted with the private key, with the public key. padding defaults to PKCS1_PADDING.

static VALUE
ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    int buf_len, pad;
    VALUE str, buffer, padding;

    GetPKeyRSA(self, pkey);
    rb_scan_args(argc, argv, "11", &buffer, &padding);
    pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
    StringValue(buffer);
    str = rb_str_new(0, ossl_rsa_buf_size(pkey));
    buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
                                 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
                                 pad);
    if (buf_len < 0) ossl_raise(eRSAError, NULL);
    rb_str_set_len(str, buf_len);

    return str;
}
public_encrypt(string) → String click to toggle source
public_encrypt(string, padding) → String

Encrypt string with the public key. padding defaults to PKCS1_PADDING. The encrypted string output can be decrypted using private_decrypt.

static VALUE
ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    int buf_len, pad;
    VALUE str, buffer, padding;

    GetPKeyRSA(self, pkey);
    rb_scan_args(argc, argv, "11", &buffer, &padding);
    pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
    StringValue(buffer);
    str = rb_str_new(0, ossl_rsa_buf_size(pkey));
    buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
                                 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
                                 pad);
    if (buf_len < 0) ossl_raise(eRSAError, NULL);
    rb_str_set_len(str, buf_len);

    return str;
}
public_key → RSA click to toggle source

Makes new RSA instance containing the public key from the private key.

static VALUE
ossl_rsa_to_public_key(VALUE self)
{
    EVP_PKEY *pkey;
    RSA *rsa;
    VALUE obj;

    GetPKeyRSA(self, pkey);
    /* err check performed by rsa_instance */
    rsa = RSAPublicKey_dup(pkey->pkey.rsa);
    obj = rsa_instance(CLASS_OF(self), rsa);
    if (obj == Qfalse) {
        RSA_free(rsa);
        ossl_raise(eRSAError, NULL);
    }
    return obj;
}
to_der → DER-format String click to toggle source

Outputs this keypair in DER encoding.

static VALUE
ossl_rsa_to_der(VALUE self)
{
    EVP_PKEY *pkey;
    int (*i2d_func)_((const RSA*, unsigned char**));
    unsigned char *p;
    long len;
    VALUE str;

    GetPKeyRSA(self, pkey);
    if(RSA_HAS_PRIVATE(pkey->pkey.rsa))
        i2d_func = i2d_RSAPrivateKey;
    else
        i2d_func = (int (*)(const RSA*, unsigned char**))i2d_RSA_PUBKEY;
    if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0)
        ossl_raise(eRSAError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_func(pkey->pkey.rsa, &p) < 0)
        ossl_raise(eRSAError, NULL);
    ossl_str_adjust(str, p);

    return str;
}
to_pem(p1 = v1, p2 = v2) click to toggle source
Alias for: export
to_s(p1 = v1, p2 = v2) click to toggle source
Alias for: export
to_text → String click to toggle source

THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!

Dumps all parameters of a keypair to a String

Don't use :-)) (It's up to you)

static VALUE
ossl_rsa_to_text(VALUE self)
{
    EVP_PKEY *pkey;
    BIO *out;
    VALUE str;

    GetPKeyRSA(self, pkey);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eRSAError, NULL);
    }
    if (!RSA_print(out, pkey->pkey.rsa, 0)) { /* offset = 0 */
        BIO_free(out);
        ossl_raise(eRSAError, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}


class Gem::Security::Policy - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Security::Policy

A Gem::Security::Policy object encapsulates the settings for verifying signed gem files. This is the base class. You can either declare an instance of this or use one of the preset security policies in Gem::Security::Policies.

In Files

  • lib/rubygems/install_update_options.rb
  • lib/rubygems/security/policy.rb

Parent

Object

Attributes

name[R]
only_signed[RW]
only_trusted[RW]
to_s[R]
verify_chain[RW]
verify_data[RW]
verify_root[RW]
verify_signer[RW]

Public Class Methods

new(name, policy = {}) click to toggle source

Create a new Gem::Security::Policy object with the given mode and options.

# File lib/rubygems/security/policy.rb, line 22
def initialize name, policy = {}, opt = {}
  require 'openssl'

  @name = name

  @opt = opt

  # Default to security
  @only_signed   = true
  @only_trusted  = true
  @verify_chain  = true
  @verify_data   = true
  @verify_root   = true
  @verify_signer = true

  policy.each_pair do |key, val|
    case key
    when :verify_data   then @verify_data   = val
    when :verify_signer then @verify_signer = val
    when :verify_chain  then @verify_chain  = val
    when :verify_root   then @verify_root   = val
    when :only_trusted  then @only_trusted  = val
    when :only_signed   then @only_signed   = val
    end
  end
end

Public Instance Methods

check_cert(signer, issuer, time) click to toggle source

Ensures that signer is valid for time and was signed by the issuer. If the issuer is nil no verification is performed.

# File lib/rubygems/security/policy.rb, line 83
def check_cert signer, issuer, time
  raise Gem::Security::Exception, 'missing signing certificate' unless
    signer

  message = "certificate #{signer.subject}"

  if not_before = signer.not_before and not_before > time then
    raise Gem::Security::Exception,
          "#{message} not valid before #{not_before}"
  end

  if not_after = signer.not_after and not_after < time then
    raise Gem::Security::Exception, "#{message} not valid after #{not_after}"
  end

  if issuer and not signer.verify issuer.public_key then
    raise Gem::Security::Exception,
          "#{message} was not issued by #{issuer.subject}"
  end

  true
end
check_chain(chain, time) click to toggle source

Verifies each certificate in chain has signed the following certificate and is valid for the given time.

# File lib/rubygems/security/policy.rb, line 53
def check_chain chain, time
  raise Gem::Security::Exception, 'missing signing chain' unless chain
  raise Gem::Security::Exception, 'empty signing chain' if chain.empty?

  begin
    chain.each_cons 2 do |issuer, cert|
      check_cert cert, issuer, time
    end

    true
  rescue Gem::Security::Exception => e
    raise Gem::Security::Exception, "invalid signing chain: #{e.message}"
  end
end
check_data(public_key, digest, signature, data) click to toggle source

Verifies that data matches the signature created by public_key and the digest algorithm.

# File lib/rubygems/security/policy.rb, line 72
def check_data public_key, digest, signature, data
  raise Gem::Security::Exception, "invalid signature" unless
    public_key.verify digest.new, signature, data.digest

  true
end
check_key(signer, key) click to toggle source

Ensures the public key of key matches the public key in signer

# File lib/rubygems/security/policy.rb, line 109
def check_key signer, key
  unless signer and key then
    return true unless @only_signed

    raise Gem::Security::Exception, 'missing key or signature'
  end

  raise Gem::Security::Exception,
    "certificate #{signer.subject} does not match the signing key" unless
      signer.public_key.to_pem == key.public_key.to_pem

  true
end
check_root(chain, time) click to toggle source

Ensures the root certificate in chain is self-signed and valid for time.

# File lib/rubygems/security/policy.rb, line 127
def check_root chain, time
  raise Gem::Security::Exception, 'missing signing chain' unless chain

  root = chain.first

  raise Gem::Security::Exception, 'missing root certificate' unless root

  raise Gem::Security::Exception,
        "root certificate #{root.subject} is not self-signed " +
        "(issuer #{root.issuer})" if
    root.issuer.to_s != root.subject.to_s # HACK to_s is for ruby 1.8

  check_cert root, root, time
end
check_trust(chain, digester, trust_dir) click to toggle source

Ensures the root of chain has a trusted certificate in trust_dir and the digests of the two certificates match according to digester

# File lib/rubygems/security/policy.rb, line 146
def check_trust chain, digester, trust_dir
  raise Gem::Security::Exception, 'missing signing chain' unless chain

  root = chain.first

  raise Gem::Security::Exception, 'missing root certificate' unless root

  path = Gem::Security.trust_dir.cert_path root

  unless File.exist? path then
    message = "root cert #{root.subject} is not trusted"

    message << " (root of signing cert #{chain.last.subject})" if
      chain.length > 1

    raise Gem::Security::Exception, message
  end

  save_cert = OpenSSL::X509::Certificate.new File.read path
  save_dgst = digester.digest save_cert.public_key.to_s

  pkey_str = root.public_key.to_s
  cert_dgst = digester.digest pkey_str

  raise Gem::Security::Exception,
        "trusted root certificate #{root.subject} checksum " +
        "does not match signing root certificate checksum" unless
    save_dgst == cert_dgst

  true
end
verify(chain, key = nil, digests = {}) click to toggle source

Verifies the certificate chain is valid, the digests match the signatures signatures created by the signer depending on the policy settings.

If key is given it is used to validate the signing certificate.

# File lib/rubygems/security/policy.rb, line 193
def verify chain, key = nil, digests = {}, signatures = {}
  if @only_signed and signatures.empty? then
    raise Gem::Security::Exception,
      "unsigned gems are not allowed by the #{name} policy"
  end

  opt       = @opt
  digester  = Gem::Security::DIGEST_ALGORITHM
  trust_dir = opt[:trust_dir]
  time      = Time.now

  _, signer_digests = digests.find do |algorithm, file_digests|
    file_digests.values.first.name == Gem::Security::DIGEST_NAME
  end

  if @verify_data then
    raise Gem::Security::Exception, 'no digests provided (probable bug)' if
      signer_digests.nil? or signer_digests.empty?
  else
    signer_digests = {}
  end

  signer = chain.last

  check_key signer, key if key

  check_cert signer, nil, time if @verify_signer

  check_chain chain, time if @verify_chain

  check_root chain, time if @verify_root

  check_trust chain, digester, trust_dir if @only_trusted

  signatures.each do |file, _|
    digest = signer_digests[file]

    raise Gem::Security::Exception, "missing digest for #{file}" unless
      digest
  end

  signer_digests.each do |file, digest|
    signature = signatures[file]

    raise Gem::Security::Exception, "missing signature for #{file}" unless
      signature

    check_data signer.public_key, digester, signature, digest if @verify_data
  end

  true
end
verify_signatures(spec, digests, signatures) click to toggle source

Extracts the certificate chain from the spec and calls verify to ensure the signatures and certificate chain is valid according to the policy..

# File lib/rubygems/security/policy.rb, line 250
def verify_signatures spec, digests, signatures
  chain = spec.cert_chain.map do |cert_pem|
    OpenSSL::X509::Certificate.new cert_pem
  end

  verify chain, nil, digests, signatures

  true
end


class Gem::Security::Signer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Security::Signer

Basic OpenSSL-based package signing class.

In Files

  • lib/rubygems/security/signer.rb

Parent

Object

Attributes

cert_chain[RW]

The chain of certificates for signing including the signing certificate

digest_algorithm[R]

The digest algorithm used to create the signature

key[RW]

The private key for the signing certificate

Public Class Methods

new(key, cert_chain) click to toggle source

Creates a new signer with an RSA key or path to a key, and a certificate chain containing X509 certificates, encoding certificates or paths to certificates.

# File lib/rubygems/security/signer.rb, line 32
def initialize key, cert_chain
  @cert_chain = cert_chain
  @key        = key

  unless @key then
    default_key  = File.join Gem.default_key_path
    @key = default_key if File.exist? default_key
  end

  unless @cert_chain then
    default_cert = File.join Gem.default_cert_path
    @cert_chain = [default_cert] if File.exist? default_cert
  end

  @digest_algorithm = Gem::Security::DIGEST_ALGORITHM
  @digest_name      = Gem::Security::DIGEST_NAME

  @key = OpenSSL::PKey::RSA.new File.read @key if
    @key and not OpenSSL::PKey::RSA === @key

  if @cert_chain then
    @cert_chain = @cert_chain.compact.map do |cert|
      next cert if OpenSSL::X509::Certificate === cert

      cert = File.read cert if File.exist? cert

      OpenSSL::X509::Certificate.new cert
    end

    load_cert_chain
  end
end

Public Instance Methods

sign(data) click to toggle source

Sign data with given digest algorithm

# File lib/rubygems/security/signer.rb, line 85
def sign data
  return unless @key

  if @cert_chain.length == 1 and @cert_chain.last.not_after < Time.now then
    re_sign_key
  end

  Gem::Security::SigningPolicy.verify @cert_chain, @key

  @key.sign @digest_algorithm.new, data
end


class Gem::Security::TrustDir - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Security::TrustDir

In Files

  • lib/rubygems/security/trust_dir.rb

Parent

Object

Constants

DEFAULT_PERMISSIONS

Attributes

dir[R]

Public Class Methods

new(dir, permissions = DEFAULT_PERMISSIONS) click to toggle source
# File lib/rubygems/security/trust_dir.rb, line 8
def initialize dir, permissions = DEFAULT_PERMISSIONS
  @dir = dir
  @permissions = permissions

  @digester = Gem::Security::DIGEST_ALGORITHM
end

Public Instance Methods

cert_path(certificate) click to toggle source

Returns the path to the trusted certificate

# File lib/rubygems/security/trust_dir.rb, line 20
def cert_path certificate
  name_path certificate.subject
end
each_certificate() { |certificate, certificate_file| ... } click to toggle source

Enumerates trusted certificates.

# File lib/rubygems/security/trust_dir.rb, line 27
def each_certificate
  return enum_for __method__ unless block_given?

  glob = File.join @dir, '*.pem'

  Dir[glob].each do |certificate_file|
    begin
      certificate = load_certificate certificate_file

      yield certificate, certificate_file
    rescue OpenSSL::X509::CertificateError
      next # HACK warn
    end
  end
end
issuer_of(certificate) click to toggle source

Returns the issuer certificate of the given certificate if it exists in the trust directory.

# File lib/rubygems/security/trust_dir.rb, line 47
def issuer_of certificate
  path = name_path certificate.issuer

  return unless File.exist? path

  load_certificate path
end
load_certificate(certificate_file) click to toggle source

Loads the given certificate_file

# File lib/rubygems/security/trust_dir.rb, line 67
def load_certificate certificate_file
  pem = File.read certificate_file

  OpenSSL::X509::Certificate.new pem
end
name_path(name) click to toggle source

Returns the path to the trusted certificate with the given ASN.1 name

# File lib/rubygems/security/trust_dir.rb, line 58
def name_path name
  digest = @digester.hexdigest name.to_s

  File.join @dir, "cert-#{digest}.pem"
end
trust_cert(certificate) click to toggle source

Add a certificate to trusted certificate list.

# File lib/rubygems/security/trust_dir.rb, line 76
def trust_cert certificate
  verify

  destination = cert_path certificate

  open destination, 'wb', @permissions[:trusted_cert] do |io|
    io.write certificate.to_pem
  end
end
verify() click to toggle source

Make sure the trust directory exists. If it does exist, make sure it's actually a directory. If not, then create it with the appropriate permissions.

# File lib/rubygems/security/trust_dir.rb, line 91
def verify
  if File.exist? @dir then
    raise Gem::Security::Exception,
      "trust directory #{@dir} is not a directory" unless
        File.directory? @dir

    FileUtils.chmod 0700, @dir
  else
    FileUtils.mkdir_p @dir, :mode => @permissions[:trust_dir]
  end
end


class Gem::Server - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Server

Gem::Server and allows users to serve gems for consumption by `gem –remote-install`.

gem_server starts an HTTP server on the given port and serves the following:

  • “/” - Browsing of gem spec files for installed gems

  • “/specs.#{Gem.marshal_version}.gz” - specs name/version/platform index

  • “/latest_specs.#{Gem.marshal_version}.gz” - latest specs name/version/platform index

  • “/quick/” - Individual gemspecs

  • “/gems” - Direct access to download the installable gems

  • “/rdoc?q=” - Search for installed rdoc documentation

Usage

gem_server = Gem::Server.new Gem.dir, 8089, false
gem_server.run

In Files

  • lib/rubygems/server.rb

Parent

Object

Included Modules

  • ERB::Util
  • Gem::UserInteraction

Constants

DOC_TEMPLATE
RDOC_CSS

CSS is copy & paste from rdoc-style.css, RDoc V1.0.1 - 20041108

RDOC_NO_DOCUMENTATION
RDOC_SEARCH_TEMPLATE
SEARCH

Attributes

spec_dirs[R]

Public Class Methods

new(gem_dirs, port, daemon, launch = nil, addresses = nil) click to toggle source
# File lib/rubygems/server.rb, line 432
def initialize(gem_dirs, port, daemon, launch = nil, addresses = nil)
  Gem::RDoc.load_rdoc
  Socket.do_not_reverse_lookup = true

  @gem_dirs  = Array gem_dirs
  @port      = port
  @daemon    = daemon
  @launch    = launch
  @addresses = addresses

  logger  = WEBrick::Log.new nil, WEBrick::BasicLog::FATAL
  @server = WEBrick::HTTPServer.new :DoNotListen => true, :Logger => logger

  @spec_dirs = @gem_dirs.map { |gem_dir| File.join gem_dir, 'specifications' }
  @spec_dirs.reject! { |spec_dir| !File.directory? spec_dir }

  reset_gems

  @have_rdoc_4_plus = nil
end
run(options) click to toggle source
# File lib/rubygems/server.rb, line 427
def self.run(options)
  new(options[:gemdir], options[:port], options[:daemon],
      options[:launch], options[:addresses]).run
end

Public Instance Methods

add_date(res) click to toggle source
# File lib/rubygems/server.rb, line 453
def add_date res
  res['date'] = @spec_dirs.map do |spec_dir|
    File.stat(spec_dir).mtime
  end.max
end
doc_root(gem_name) click to toggle source
# File lib/rubygems/server.rb, line 459
def doc_root gem_name
  if have_rdoc_4_plus? then
    "/doc_root/#{gem_name}/"
  else
    "/doc_root/#{gem_name}/rdoc/index.html"
  end
end
have_rdoc_4_plus?() click to toggle source
# File lib/rubygems/server.rb, line 467
def have_rdoc_4_plus?
  @have_rdoc_4_plus ||=
    Gem::Requirement.new('>= 4.0.0.preview2').satisfied_by? Gem::RDoc.rdoc_version
end
latest_specs(req, res) click to toggle source
# File lib/rubygems/server.rb, line 472
def latest_specs(req, res)
  reset_gems

  res['content-type'] = 'application/x-gzip'

  add_date res

  latest_specs = Gem::Specification.latest_specs

  specs = latest_specs.sort.map do |spec|
    platform = spec.original_platform || Gem::Platform::RUBY
    [spec.name, spec.version, platform]
  end

  specs = Marshal.dump specs

  if req.path =~ /\.gz$/ then
    specs = Gem.gzip specs
    res['content-type'] = 'application/x-gzip'
  else
    res['content-type'] = 'application/octet-stream'
  end

  if req.request_method == 'HEAD' then
    res['content-length'] = specs.length
  else
    res.body << specs
  end
end
launch() click to toggle source
# File lib/rubygems/server.rb, line 823
def launch
  listeners = @server.listeners.map{|l| l.addr[2] }

  # TODO: 0.0.0.0 == any, not localhost.
  host = listeners.any?{|l| l == '0.0.0.0'} ? 'localhost' : listeners.first

  say "Launching browser to http://#{host}:#{@port}"

  system("#{@launch} http://#{host}:#{@port}")
end
listen(addresses = @addresses) click to toggle source

Creates server sockets based on the addresses option. If no addresses were given a server socket for all interfaces is created.

# File lib/rubygems/server.rb, line 506
def listen addresses = @addresses
  addresses = [nil] unless addresses

  listeners = 0

  addresses.each do |address|
    begin
      @server.listen address, @port
      @server.listeners[listeners..-1].each do |listener|
        host, port = listener.addr.values_at 2, 1
        host = "[#{host}]" if host =~ /:/ # we don't reverse lookup
        say "Server started at http://#{host}:#{port}"
      end

      listeners = @server.listeners.length
    rescue SystemCallError
      next
    end
  end

  if @server.listeners.empty? then
    say "Unable to start a server."
    say "Check for running servers or your --bind and --port arguments"
    terminate_interaction 1
  end
end
quick(req, res) click to toggle source
# File lib/rubygems/server.rb, line 533
def quick(req, res)
  reset_gems

  res['content-type'] = 'text/plain'
  add_date res

  case req.request_uri.path
  when %r^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)-([0-9.]+)(-.*?)?\.gemspec\.rz$| then
    marshal_format, name, version, platform = $1, $2, $3, $4
    specs = Gem::Specification.find_all_by_name name, version

    selector = [name, version, platform].map(&:inspect).join ' '

    platform = if platform then
                 Gem::Platform.new platform.sub(/^-/, '')
               else
                 Gem::Platform::RUBY
               end

    specs = specs.select { |s| s.platform == platform }

    if specs.empty? then
      res.status = 404
      res.body = "No gems found matching #{selector}"
    elsif specs.length > 1 then
      res.status = 500
      res.body = "Multiple gems found matching #{selector}"
    elsif marshal_format then
      res['content-type'] = 'application/x-deflate'
      res.body << Gem.deflate(Marshal.dump(specs.first))
    end
  else
    raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found."
  end
end
rdoc(req, res) click to toggle source

Can be used for quick navigation to the rdoc documentation. You can then define a search shortcut for your browser. E.g. in Firefox connect 'shortcut:rdoc' to localhost:8808/rdoc?q=%s template. Then you can directly open the ActionPack documentation by typing 'rdoc actionp'. If there are multiple hits for the search term, they are presented as a list with links.

Search algorithm aims for an intuitive search:

  1. first try to find the gems and documentation folders which name starts with the search term

  2. search for entries, that contain the search term

  3. show all the gems

If there is only one search hit, user is immediately redirected to the documentation for the particular gem, otherwise a list with results is shown.

Additional trick - install documentation for ruby core

Note: please adjust paths accordingly use for example 'locate yaml.rb' and 'gem environment' to identify directories, that are specific for your local installation

  1. install ruby sources

    cd /usr/src
sudo apt-get source ruby

  2. generate documentation

    rdoc -o /usr/lib/ruby/gems/1.8/doc/core/rdoc \
  /usr/lib/ruby/1.8 ruby1.8-1.8.7.72

By typing 'rdoc core' you can now access the core documentation

# File lib/rubygems/server.rb, line 690
def rdoc(req, res)
  query = req.query['q']
  show_rdoc_for_pattern("#{query}*", res) && return
  show_rdoc_for_pattern("*#{query}*", res) && return

  template = ERB.new RDOC_NO_DOCUMENTATION

  res['content-type'] = 'text/html'
  res.body = template.result binding
end
root(req, res) click to toggle source
# File lib/rubygems/server.rb, line 569
def root(req, res)
  reset_gems

  add_date res

  raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found." unless
    req.path == '/'

  specs = []
  total_file_count = 0

  Gem::Specification.each do |spec|
    total_file_count += spec.files.size
    deps = spec.dependencies.map { |dep|
      {
        "name"    => dep.name,
        "type"    => dep.type,
        "version" => dep.requirement.to_s,
      }
    }

    deps = deps.sort_by { |dep| [dep["name"].downcase, dep["version"]] }
    deps.last["is_last"] = true unless deps.empty?

    # executables
    executables = spec.executables.sort.collect { |exec| {"executable" => exec} }
    executables = nil if executables.empty?
    executables.last["is_last"] = true if executables

    specs << {
      "authors"             => spec.authors.sort.join(", "),
      "date"                => spec.date.to_s,
      "dependencies"        => deps,
      "doc_path"            => doc_root(spec.full_name),
      "executables"         => executables,
      "only_one_executable" => (executables && executables.size == 1),
      "full_name"           => spec.full_name,
      "has_deps"            => !deps.empty?,
      "homepage"            => spec.homepage,
      "name"                => spec.name,
      "rdoc_installed"      => Gem::RDoc.new(spec).rdoc_installed?,
      "ri_installed"        => Gem::RDoc.new(spec).ri_installed?,
      "summary"             => spec.summary,
      "version"             => spec.version.to_s,
    }
  end

  specs << {
    "authors" => "Chad Fowler, Rich Kilmer, Jim Weirich, Eric Hodel and others",
    "dependencies" => [],
    "doc_path" => doc_root("rubygems-#{Gem::VERSION}"),
    "executables" => [{"executable" => 'gem', "is_last" => true}],
    "only_one_executable" => true,
    "full_name" => "rubygems-#{Gem::VERSION}",
    "has_deps" => false,
    "homepage" => "http://docs.rubygems.org/",
    "name" => 'rubygems',
    "ri_installed" => true,
    "summary" => "RubyGems itself",
    "version" => Gem::VERSION,
  }

  specs = specs.sort_by { |spec| [spec["name"].downcase, spec["version"]] }
  specs.last["is_last"] = true

  # tag all specs with first_name_entry
  last_spec = nil
  specs.each do |spec|
    is_first = last_spec.nil? || (last_spec["name"].downcase != spec["name"].downcase)
    spec["first_name_entry"] = is_first
    last_spec = spec
  end

  # create page from template
  template = ERB.new(DOC_TEMPLATE)
  res['content-type'] = 'text/html'

  values = { "gem_count" => specs.size.to_s, "specs" => specs,
             "total_file_count" => total_file_count.to_s }

  # suppress 1.9.3dev warning about unused variable
  values = values

  result = template.result binding
  res.body = result
end
run() click to toggle source
# File lib/rubygems/server.rb, line 747
def run
  listen

  WEBrick::Daemon.start if @daemon

  @server.mount_proc "/specs.#{Gem.marshal_version}", method(:specs)
  @server.mount_proc "/specs.#{Gem.marshal_version}.gz", method(:specs)

  @server.mount_proc "/latest_specs.#{Gem.marshal_version}",
                     method(:latest_specs)
  @server.mount_proc "/latest_specs.#{Gem.marshal_version}.gz",
                     method(:latest_specs)

  @server.mount_proc "/quick/", method(:quick)

  @server.mount_proc("/gem-server-rdoc-style.css") do |req, res|
    res['content-type'] = 'text/css'
    add_date res
    res.body << RDOC_CSS
  end

  @server.mount_proc "/", method(:root)

  @server.mount_proc "/rdoc", method(:rdoc)

  file_handlers = {
    '/gems' => '/cache/',
  }

  if have_rdoc_4_plus? then
    @server.mount '/doc_root', RDoc::Servlet, '/doc_root'
  else
    file_handlers['/doc_root'] = '/doc/'
  end

  @gem_dirs.each do |gem_dir|
    file_handlers.each do |mount_point, mount_dir|
      @server.mount(mount_point, WEBrick::HTTPServlet::FileHandler,
                    File.join(gem_dir, mount_dir), true)
    end
  end

  trap("INT") { @server.shutdown; exit! }
  trap("TERM") { @server.shutdown; exit! }

  launch if @launch

  @server.start
end
show_rdoc_for_pattern(pattern, res) click to toggle source

Returns true and prepares http response, if rdoc for the requested gem name pattern was found.

The search is based on the file system content, not on the gems metadata. This allows additional documentation folders like 'core' for the ruby core documentation - just put it underneath the main doc folder.

# File lib/rubygems/server.rb, line 716
def show_rdoc_for_pattern(pattern, res)
  found_gems = Dir.glob("{#{@gem_dirs.join ','}}/doc/#{pattern}").select {|path|
    File.exist? File.join(path, 'rdoc/index.html')
  }
  case found_gems.length
  when 0
    return false
  when 1
    new_path = File.basename(found_gems[0])
    res.status = 302
    res['Location'] = doc_root new_path
    return true
  else
    doc_items = []
    found_gems.each do |file_name|
      base_name = File.basename(file_name)
      doc_items << {
        :name    => base_name,
        :url     => doc_root(new_path),
        :summary => ''
      }
    end

    template = ERB.new(RDOC_SEARCH_TEMPLATE)
    res['content-type'] = 'text/html'
    result = template.result binding
    res.body = result
    return true
  end
end
specs(req, res) click to toggle source
# File lib/rubygems/server.rb, line 797
def specs(req, res)
  reset_gems

  add_date res

  specs = Gem::Specification.sort_by(&:sort_obj).map do |spec|
    platform = spec.original_platform || Gem::Platform::RUBY
    [spec.name, spec.version, platform]
  end

  specs = Marshal.dump specs

  if req.path =~ /\.gz$/ then
    specs = Gem.gzip specs
    res['content-type'] = 'application/x-gzip'
  else
    res['content-type'] = 'application/octet-stream'
  end

  if req.request_method == 'HEAD' then
    res['content-length'] = specs.length
  else
    res.body << specs
  end
end


class Gem::SilentUI - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::SilentUI

SilentUI is a UI choice that is absolutely silent.

In Files

  • lib/rubygems/user_interaction.rb

Parent

Gem::StreamUI

Public Class Methods

new() click to toggle source
# File lib/rubygems/user_interaction.rb, line 550
def initialize
  reader, writer = nil, nil

  begin
    reader = File.open('/dev/null', 'r')
    writer = File.open('/dev/null', 'w')
  rescue Errno::ENOENT
    reader = File.open('nul', 'r')
    writer = File.open('nul', 'w')
  end

  super reader, writer, writer, false
end

Public Instance Methods

download_reporter(*args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 564
def download_reporter(*args)
  SilentDownloadReporter.new(@outs, *args)
end
progress_reporter(*args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 568
def progress_reporter(*args)
  SilentProgressReporter.new(@outs, *args)
end


class Gem::Source - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Source

In Files

  • lib/rubygems/source.rb

Parent

Object

Included Modules

  • Comparable

Constants

FILES

Attributes

uri[R]

Public Class Methods

new(uri) click to toggle source
# File lib/rubygems/source.rb, line 11
def initialize(uri)
  unless uri.kind_of? URI
    uri = URI.parse(uri.to_s)
  end

  @uri = uri
  @api_uri = nil
end

Public Instance Methods

<=>(other) click to toggle source
# File lib/rubygems/source.rb, line 27
def <=>(other)
  if !@uri
    return 0 unless other.uri
    return -1
  end

  return 1 if !other.uri

  @uri.to_s <=> other.uri.to_s
end
==(other) click to toggle source
# File lib/rubygems/source.rb, line 40
def ==(other)
  case other
  when self.class
    @uri == other.uri
  else
    false
  end
end
Also aliased as: eql?
api_uri() click to toggle source
# File lib/rubygems/source.rb, line 22
def api_uri
  require 'rubygems/remote_fetcher'
  @api_uri ||= Gem::RemoteFetcher.fetcher.api_endpoint uri
end
cache_dir(uri) click to toggle source

Returns the local directory to write uri to.

# File lib/rubygems/source.rb, line 58
def cache_dir(uri)
  # Correct for windows paths
  escaped_path = uri.path.sub(/^\/([a-z]):\//, '/\1-/')
  root = File.join Gem.user_home, '.gem', 'specs'
  File.join root, "#{uri.host}%#{uri.port}", File.dirname(escaped_path)
end
download(spec, dir=Dir.pwd) click to toggle source
# File lib/rubygems/source.rb, line 145
def download(spec, dir=Dir.pwd)
  fetcher = Gem::RemoteFetcher.fetcher
  fetcher.download spec, @uri.to_s, dir
end
eql?(other) click to toggle source
Alias for: ==
fetch_spec(name) click to toggle source
# File lib/rubygems/source.rb, line 74
def fetch_spec(name)
  fetcher = Gem::RemoteFetcher.fetcher

  spec_file_name = name.spec_name

  uri = @uri + "#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}"

  cache_dir = cache_dir uri

  local_spec = File.join cache_dir, spec_file_name

  if File.exist? local_spec then
    spec = Gem.read_binary local_spec
    spec = Marshal.load(spec) rescue nil
    return spec if spec
  end

  uri.path << '.rz'

  spec = fetcher.fetch_path uri
  spec = Gem.inflate spec

  if update_cache? then
    FileUtils.mkdir_p cache_dir

    open local_spec, 'wb' do |io|
      io.write spec
    end
  end

  # TODO: Investigate setting Gem::Specification#loaded_from to a URI
  Marshal.load spec
end
hash() click to toggle source
# File lib/rubygems/source.rb, line 51
def hash
  @uri.hash
end
load_specs(type) click to toggle source

Loads type kind of specs fetching from +@uri+ if the on-disk cache is out of date.

type is one of the following:

:released => Return the list of all released specs :latest => Return the list of only the highest version of each gem :prerelease => Return the list of all prerelease only specs

# File lib/rubygems/source.rb, line 119
def load_specs(type)
  file       = FILES[type]
  fetcher    = Gem::RemoteFetcher.fetcher
  file_name  = "#{file}.#{Gem.marshal_version}"
  spec_path  = @uri + "#{file_name}.gz"
  cache_dir  = cache_dir spec_path
  local_file = File.join(cache_dir, file_name)
  retried    = false

  FileUtils.mkdir_p cache_dir if update_cache?

  spec_dump = fetcher.cache_update_path spec_path, local_file, update_cache?

  begin
    Gem::NameTuple.from_list Marshal.load(spec_dump)
  rescue ArgumentError
    if update_cache? && !retried
      FileUtils.rm local_file
      retried = true
      retry
    else
      raise Gem::Exception.new("Invalid spec cache file in #{local_file}")
    end
  end
end
update_cache?() click to toggle source
# File lib/rubygems/source.rb, line 65
def update_cache?
  @update_cache ||=
    begin
      File.stat(Gem.user_home).uid == Process.uid
    rescue Errno::ENOENT
      false
    end
end


class Gem::Source::Local - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Source::Local

In Files

  • lib/rubygems/source_local.rb

Parent

Gem::Source

Public Class Methods

new() click to toggle source
# File lib/rubygems/source_local.rb, line 4
def initialize
  @uri = nil
end

Public Instance Methods

download(spec, cache_dir=nil) click to toggle source
# File lib/rubygems/source_local.rb, line 83
def download(spec, cache_dir=nil)
  load_specs :complete

  @specs.each do |name, data|
    return data[0] if data[1].spec == spec
  end

  raise Gem::Exception, "Unable to find file for '#{spec.full_name}'"
end
fetch_spec(name) click to toggle source
# File lib/rubygems/source_local.rb, line 73
def fetch_spec(name)
  load_specs :complete

  if data = @specs[name]
    data.last.spec
  else
    raise Gem::Exception, "Unable to find spec for '#{name}'"
  end
end
find_gem(gem_name, version=Gem::Requirement.default, prerelease=false) click to toggle source
# File lib/rubygems/source_local.rb, line 50
def find_gem(gem_name, version=Gem::Requirement.default,
             prerelease=false)
  load_specs :complete

  found = []

  @specs.each do |n, data|
    if n.name == gem_name
      s = data[1].spec

      if version.satisfied_by?(s.version)
        if prerelease
          found << s
        elsif !s.version.prerelease?
          found << s
        end
      end
    end
  end

  found.sort_by { |s| s.version }.last
end
load_specs(type) click to toggle source
# File lib/rubygems/source_local.rb, line 8
def load_specs(type)
  names = []

  @specs = {}

  Dir["*.gem"].each do |file|
    begin
      pkg = Gem::Package.new(file)
    rescue SystemCallError, Gem::Package::FormatError
      # ignore
    else
      tup = pkg.spec.name_tuple
      @specs[tup] = [File.expand_path(file), pkg]

      case type
      when :released
        unless pkg.spec.version.prerelease?
          names << pkg.spec.name_tuple
        end
      when :prerelease
        if pkg.spec.version.prerelease?
          names << pkg.spec.name_tuple
        end
      when :latest
        tup = pkg.spec.name_tuple

        cur = names.find { |x| x.name == tup.name }
        if !cur
          names << tup
        elsif cur.version < tup.version
          names.delete cur
          names << tup
        end
      else
        names << pkg.spec.name_tuple
      end
    end
  end

  names
end


class Gem::Source::SpecificFile - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Source::SpecificFile

In Files

  • lib/rubygems/source_specific_file.rb

Parent

Gem::Source

Attributes

spec[R]

Public Class Methods

new(file) click to toggle source
# File lib/rubygems/source_specific_file.rb, line 2
def initialize(file)
  @uri = nil
  @path = ::File.expand_path(file)

  @package = Gem::Package.new @path
  @spec = @package.spec
  @name = @spec.name_tuple
end

Public Instance Methods

download(spec, dir=nil) click to toggle source
# File lib/rubygems/source_specific_file.rb, line 23
def download(spec, dir=nil)
  return @path if spec == @spec
  raise Gem::Exception, "Unable to download '#{spec.full_name}'"
end
fetch_spec(name) click to toggle source
# File lib/rubygems/source_specific_file.rb, line 17
def fetch_spec(name)
  return @spec if name == @name
  raise Gem::Exception, "Unable to find '#{name}'"
  @spec
end
load_specs(*a) click to toggle source
# File lib/rubygems/source_specific_file.rb, line 13
def load_specs(*a)
  [@name]
end


class Gem::SourceFetchProblem - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::SourceFetchProblem

An error that indicates we weren't able to fetch some data from a source

In Files

  • lib/rubygems/errors.rb

Parent

Gem::ErrorReason

Attributes

error[R]
source[R]

Public Class Methods

new(source, error) click to toggle source
# File lib/rubygems/errors.rb, line 78
def initialize(source, error)
  @source = source
  @error = error
end

Public Instance Methods

wordy() click to toggle source
# File lib/rubygems/errors.rb, line 85
def wordy
  "Unable to download data from #{@source.uri} - #{@error.message}"
end


class Gem::SourceList - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::SourceList

In Files

  • lib/rubygems/source_list.rb

Parent

Object

Attributes

sources[R]

Public Class Methods

from(ary) click to toggle source
# File lib/rubygems/source_list.rb, line 10
def self.from(ary)
  list = new

  if ary
    ary.each do |x|
      list << x
    end
  end

  return list
end
new() click to toggle source
# File lib/rubygems/source_list.rb, line 4
def initialize
  @sources = []
end

Public Instance Methods

<<(obj) click to toggle source
# File lib/rubygems/source_list.rb, line 26
def <<(obj)
  src = case obj
        when URI
          Gem::Source.new(obj)
        when Gem::Source
          obj
        else
          Gem::Source.new(URI.parse(obj))
        end

  @sources << src
  src
end
==(other) click to toggle source
# File lib/rubygems/source_list.rb, line 58
def ==(other)
  to_a == other
end
delete(uri) click to toggle source
# File lib/rubygems/source_list.rb, line 80
def delete(uri)
  if uri.kind_of? Gem::Source
    @sources.delete uri
  else
    @sources.delete_if { |x| x.uri.to_s == uri.to_s }
  end
end
each() { |uri.to_s| ... } click to toggle source
# File lib/rubygems/source_list.rb, line 50
def each
  @sources.each { |s| yield s.uri.to_s }
end
each_source(&b) click to toggle source
# File lib/rubygems/source_list.rb, line 54
def each_source(&b)
  @sources.each(&b)
end
first() click to toggle source
# File lib/rubygems/source_list.rb, line 68
def first
  @sources.first
end
include?(other) click to toggle source
# File lib/rubygems/source_list.rb, line 72
def include?(other)
  if other.kind_of? Gem::Source
    @sources.include? other
  else
    @sources.find { |x| x.uri.to_s == other.to_s }
  end
end
initialize_copy(other) click to toggle source
# File lib/rubygems/source_list.rb, line 22
def initialize_copy(other)
  @sources = @sources.dup
end
replace(other) click to toggle source
# File lib/rubygems/source_list.rb, line 40
def replace(other)
  @sources.clear

  other.each do |x|
    self << x
  end

  self
end
to_a() click to toggle source
# File lib/rubygems/source_list.rb, line 62
def to_a
  @sources.map { |x| x.uri.to_s }
end
Also aliased as: to_ary
to_ary() click to toggle source
Alias for: to_a


class Gem::SpecFetcher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::SpecFetcher

SpecFetcher handles metadata updates from remote gem repositories.

In Files

  • lib/rubygems/spec_fetcher.rb

Parent

Object

Included Modules

  • Gem::UserInteraction
  • Gem::Text

Public Class Methods

fetcher() click to toggle source
# File lib/rubygems/spec_fetcher.rb, line 32
def self.fetcher
  @fetcher ||= new
end
new() click to toggle source
# File lib/rubygems/spec_fetcher.rb, line 40
def initialize
  @dir = File.join Gem.user_home, '.gem', 'specs'
  @update_cache =
    begin
      File.stat(Gem.user_home).uid == Process.uid
    rescue Errno::EACCES, Errno::ENOENT
      false
    end

  @specs = {}
  @latest_specs = {}
  @prerelease_specs = {}

  @caches = {
    :latest => @latest_specs,
    :prerelease => @prerelease_specs,
    :released => @specs,
  }

  @fetcher = Gem::RemoteFetcher.fetcher
end

Public Instance Methods

available_specs(type) click to toggle source

Returns a list of gems available for each source in Gem.sources.

type can be one of 3 values: :released => Return the list of all released specs :complete => Return the list of all specs :latest => Return the list of only the highest version of each gem :prerelease => Return the list of all prerelease only specs

# File lib/rubygems/spec_fetcher.rb, line 191
def available_specs(type)
  errors = []
  list = {}

  Gem.sources.each_source do |source|
    begin
      names = case type
              when :latest
                tuples_for source, :latest
              when :released
                tuples_for source, :released
              when :complete
                tuples_for(source, :prerelease, true) +
                  tuples_for(source, :released)
              when :prerelease
                tuples_for(source, :prerelease)
              else
                raise Gem::Exception, "Unknown type - :#{type}"
              end
    rescue Gem::RemoteFetcher::FetchError => e
      errors << Gem::SourceFetchProblem.new(source, e)
    else
      list[source] = names
    end
  end

  [list, errors]
end
detect(type=:complete) { |tup| ... } click to toggle source

Return all gem name tuples who's names match obj

# File lib/rubygems/spec_fetcher.rb, line 117
def detect(type=:complete)
  tuples = []

  list, _ = available_specs(type)
  list.each do |source, specs|
    specs.each do |tup|
      if yield(tup)
        tuples << [tup, source]
      end
    end
  end

  tuples
end
search_for_dependency(dependency, matching_platform=true) click to toggle source

Find and fetch gem name tuples that match dependency.

If matching_platform is false, gems for all platforms are returned.

# File lib/rubygems/spec_fetcher.rb, line 68
def search_for_dependency(dependency, matching_platform=true)
  found = {}

  rejected_specs = {}

  if dependency.prerelease?
    type = :complete
  elsif dependency.latest_version?
    type = :latest
  else
    type = :released
  end

  list, errors = available_specs(type)
  list.each do |source, specs|
    found[source] = specs.select do |tup|
      if dependency.match?(tup)
        if matching_platform and !Gem::Platform.match(tup.platform)
          pm = (
            rejected_specs[dependency] ||=                  Gem::PlatformMismatch.new(tup.name, tup.version))
          pm.add_platform tup.platform
          false
        else
          true
        end
      end
    end
  end

  errors += rejected_specs.values

  tuples = []

  found.each do |source, specs|
    specs.each do |s|
      tuples << [s, source]
    end
  end

  tuples = tuples.sort_by { |x| x[0] }

  return [tuples, errors]
end
spec_for_dependency(dependency, matching_platform=true) click to toggle source

Find and fetch specs that match dependency.

If matching_platform is false, gems for all platforms are returned.

# File lib/rubygems/spec_fetcher.rb, line 138
def spec_for_dependency(dependency, matching_platform=true)
  tuples, errors = search_for_dependency(dependency, matching_platform)

  specs = []
  tuples.each do |tup, source|
    begin
      spec = source.fetch_spec(tup)
    rescue Gem::RemoteFetcher::FetchError => e
      errors << Gem::SourceFetchProblem.new(source, e)
    else
      specs << [spec, source]
    end
  end

  return [specs, errors]
end
suggest_gems_from_name(gem_name) click to toggle source

Suggests gems based on the supplied gem_name. Returns an array of alternative gem names.

# File lib/rubygems/spec_fetcher.rb, line 159
def suggest_gems_from_name gem_name
  gem_name        = gem_name.downcase.tr('_-', '')
  max             = gem_name.size / 2
  names           = available_specs(:complete).first.values.flatten(1)

  matches = names.map { |n|
    next unless n.match_platform?

    distance = levenshtein_distance gem_name, n.name.downcase.tr('_-', '')

    next if distance >= max

    return [n.name] if distance == 0

    [n.name, distance]
  }.compact

  matches = matches.uniq.sort_by { |name, dist| dist }

  matches.first(5).map { |name, dist| name }
end
tuples_for(source, type, gracefully_ignore=false) click to toggle source
# File lib/rubygems/spec_fetcher.rb, line 220
def tuples_for(source, type, gracefully_ignore=false)
  cache = @caches[type]

  if gracefully_ignore
    begin
      cache[source.uri] ||= source.load_specs(type)
    rescue Gem::RemoteFetcher::FetchError
      []
    end
  else
    cache[source.uri] ||= source.load_specs(type)
  end
end


class Gem::SpecificGemNotFoundException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::SpecificGemNotFoundException

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::GemNotFoundException

Attributes

errors[R]
name[R]
version[R]

Public Class Methods

new(name, version, errors=nil) click to toggle source
# File lib/rubygems/exceptions.rb, line 57
def initialize(name, version, errors=nil)
  super "Could not find a valid gem '#{name}' (#{version}) locally or in a repository"

  @name = name
  @version = version
  @errors = errors
end


class Gem::Specification - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Specification

The Specification class contains the information for a Gem. Typically defined in a .gemspec file or a Rakefile, and looks like this:

Gem::Specification.new do |s|
  s.name        = 'example'
  s.version     = '0.1.0'
  s.summary     = "This is an example!"
  s.description = "Much longer explanation of the example!"
  s.authors     = ["Ruby Coder"]
  s.email       = 'rubycoder@example.com'
  s.files       = ["lib/example.rb"]
  s.homepage    = 'https://rubygems.org/gems/example'
end

Starting in RubyGems 1.9.0, a Specification can hold arbitrary metadata. This metadata is accessed via #metadata and has the following restrictions:

  • Must be a Hash object

  • All keys and values must be Strings

  • Keys can be a maximum of 128 bytes and values can be a maximum of 1024 bytes

  • All strings must be UTF8, no binary data is allowed

For example, to add metadata for the location of a bugtracker:

s.metadata = { "bugtracker" => "http://somewhere.com/blah" }

In Files

  • lib/rubygems/specification.rb

Parent

Object

Constants

CURRENT_SPECIFICATION_VERSION

The specification version applied to any new Specification instances created. This should be bumped whenever something in the spec format changes.

Specification Version History:

spec   ruby
 ver    ver yyyy-mm-dd description
  -1 <0.8.0            pre-spec-version-history
   1  0.8.0 2004-08-01 Deprecated "test_suite_file" for "test_files"
                       "test_file=x" is a shortcut for "test_files=[x]"
   2  0.9.5 2007-10-01 Added "required_rubygems_version"
                       Now forward-compatible with future versions
   3  1.3.2 2009-01-03 Added Fixnum validation to specification_version
   4  1.9.0 2011-06-07 Added metadata
MARSHAL_FIELDS
NONEXISTENT_SPECIFICATION_VERSION

The version number of a specification that does not specify one (i.e. RubyGems 0.7 or earlier).

SPECIFICATION_VERSION_HISTORY

An informal list of changes to the specification. The highest-valued key should be equal to the CURRENT_SPECIFICATION_VERSION.

TODAY

Optional gemspec attributes

↑ top

Attributes

bindir[RW]

The path in the gem for executable scripts. Usually 'bin'

Usage:

spec.bindir = 'bin'
cert_chain[RW]

The certificate chain used to sign this gem. See Gem::Security for details.

description[R]

A long description of this gem

The description should be more detailed than the summary.

Usage:

spec.description = <<-EOF
  Rake is a Make-like program implemented in Ruby. Tasks and
  dependencies are specified in standard Ruby syntax.
EOF
email[RW]

A contact email address (or addresses) for this gem

Usage:

spec.email = 'john.jones@example.com'
spec.email = ['jack@example.com', 'jill@example.com']
homepage[RW]

The URL of this gem's home page

Usage:

spec.homepage = 'http://rake.rubyforge.org'
metadata[RW]

:attr_accessor: metadata

Arbitrary metadata for this gem. An instance of Hash.

metadata is simply a Symbol => String association that contains arbitary data that could be useful to other consumers.

post_install_message[RW]

A message that gets displayed after the gem is installed.

Usage:

spec.post_install_message = "Thanks for installing!"
signing_key[RW]

The key used to sign this gem. See Gem::Security for details.

Public Instance Methods

add_development_dependency(gem, *requirements) click to toggle source

Adds a development dependency named gem with requirements to this gem.

Usage:

spec.add_development_dependency 'example', '~> 1.1', '>= 1.1.4'

Development dependencies aren't installed by default and aren't activated when a gem is required.

# File lib/rubygems/specification.rb, line 400
def add_development_dependency(gem, *requirements)
  add_dependency_with_type(gem, :development, *requirements)
end
add_runtime_dependency(gem, *requirements) click to toggle source

Adds a runtime dependency named gem with requirements to this gem.

Usage:

spec.add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4'
# File lib/rubygems/specification.rb, line 411
def add_runtime_dependency(gem, *requirements)
  add_dependency_with_type(gem, :runtime, *requirements)
end
Also aliased as: add_dependency
author=(o) click to toggle source

Singular writer for authors

Usage:

spec.author = 'John Jones'
# File lib/rubygems/specification.rb, line 422
def author= o
  self.authors = [o]
end
authors=(value) click to toggle source

Sets the list of authors, ensuring it is an array.

Usage:

spec.authors = ['John Jones', 'Mary Smith']
# File lib/rubygems/specification.rb, line 433
def authors= value
  @authors = Array(value).flatten.grep(String)
end
executables() click to toggle source

Executables included in the gem.

For example, the rake gem has rake as an executable. You don’t specify the full path (as in bin/rake); all application-style files are expected to be found in bindir. These files must be executable ruby files. Files that use bash or other interpreters will not work.

Usage:

spec.executables << 'rake'
# File lib/rubygems/specification.rb, line 449
def executables
  @executables ||= []
end
extensions() click to toggle source

Extensions to build when installing the gem, specifically the paths to extconf.rb-style files used to compile extensions.

These files will be run when the gem is installed, causing the C (or whatever) code to be compiled on the user’s machine.

Usage:

spec.extensions << 'ext/rmagic/extconf.rb'

See Gem::Ext::Builder for information about writing extensions for gems.

# File lib/rubygems/specification.rb, line 466
def extensions
  @extensions ||= []
end
extra_rdoc_files() click to toggle source

Extra files to add to RDoc such as README or doc/examples.txt

When the user elects to generate the RDoc documentation for a gem (typically at install time), all the library files are sent to RDoc for processing. This option allows you to have some non-code files included for a more complete set of documentation.

Usage:

spec.extra_rdoc_files = ['README', 'doc/user-guide.txt']
# File lib/rubygems/specification.rb, line 482
def extra_rdoc_files
  @extra_rdoc_files ||= []
end
license=(o) click to toggle source

The license for this gem.

The license must be a short name, no more than 64 characters.

This should just be the name of your license. The full text of the license should be inside of the gem when you build it.

You can set multiple licenses with licenses=

Usage:

spec.license = 'MIT'
# File lib/rubygems/specification.rb, line 499
def license=o
  self.licenses = [o]
end
licenses=(licenses) click to toggle source

The license(s) for the library.

Each license must be a short name, no more than 64 characters.

This should just be the name of your license. The full text of the license should be inside of the gem when you build it.

Usage:

spec.licenses = ['MIT', 'GPL-2']
# File lib/rubygems/specification.rb, line 514
def licenses= licenses
  @licenses = Array licenses
end
rdoc_options() click to toggle source

Specifies the rdoc options to be used when generating API documentation.

Usage:

spec.rdoc_options << '--title' << 'Rake -- Ruby Make' <<
  '--main' << 'README' <<
  '--line-numbers'
# File lib/rubygems/specification.rb, line 527
def rdoc_options
  @rdoc_options ||= []
end
required_ruby_version=(req) click to toggle source

The version of Ruby required by this gem. The ruby version can be specified to the patch-level:

$ ruby -v -e 'p Gem.ruby_version'
ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]
#<Gem::Version "2.0.0.247">

Usage:

# This gem will work with 1.8.6 or greater...
spec.required_ruby_version = '>= 1.8.6'

# Only with ruby 2.0.x
spec.required_ruby_version = '~> 2.0'
# File lib/rubygems/specification.rb, line 547
def required_ruby_version= req
  @required_ruby_version = Gem::Requirement.create req
end
requirements() click to toggle source

Lists the external (to RubyGems) requirements that must be met for this gem to work. It's simply information for the user.

Usage:

spec.requirements << 'libmagick, v6.0'
spec.requirements << 'A good graphics card'
# File lib/rubygems/specification.rb, line 560
def requirements
  @requirements ||= []
end
test_files=(files) click to toggle source

A collection of unit test files. They will be loaded as unit tests when the user requests a gem to be unit tested.

Usage:

spec.test_files = Dir.glob('test/tc_*.rb')
spec.test_files = ['tests/test-suite.rb']
# File lib/rubygems/specification.rb, line 572
def test_files= files
  @test_files = Array files
end

Required gemspec attributes

↑ top

Attributes

name[RW]

This gem's name.

Usage:

spec.name = 'rake'
require_paths[RW]

Paths in the gem to add to $LOAD_PATH when this gem is activated.

If you have an extension you do not need to add "ext" to the require path, the extension build process will copy the extension files into “lib” for you.

The default value is "lib"

Usage:

# If all library files are in the root directory...
spec.require_path = '.'
rubygems_version[RW]

The version of RubyGems used to create this gem.

Do not set this, it is set automatically when the gem is packaged.

summary[R]

A short summary of this gem's description. Displayed in `gem list -d`.

The description should be more detailed than the summary.

Usage:

spec.summary = "This is a small summary of my gem"
version[R]

This gem's version.

The version string can contain numbers and periods, such as 1.0.0. A gem is a 'prerelease' gem if the version has a letter in it, such as 1.0.0.pre.

Usage:

spec.version = '0.4.1'

Public Instance Methods

files() click to toggle source

Files included in this gem. You cannot append to this accessor, you must assign to it.

Only add files you can require to this list, not directories, etc.

Directories are automatically stripped from this list when building a gem, other non-files cause an error.

Usage:

require 'rake'
spec.files = FileList['lib     .rb',
                      'bin/*',
                      '[A-Z]*',
                      'test/   *'].to_a

# or without Rake...
spec.files = Dir['lib/   *.rb'] + Dir['bin/*']
spec.files += Dir['[A-Z]*'] + Dir['test/**/*']
spec.files.reject! { |fn| fn.include? "CVS" }

# File lib/rubygems/specification.rb, line 303
def files
  # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks)
  # DOC: Why isn't it normal? Why does it suck? How can we fix this?
  @files = [@files,
            @test_files,
            add_bindir(@executables),
            @extra_rdoc_files,
            @extensions,
           ].flatten.uniq.compact
end
platform=(platform) click to toggle source

The platform this gem runs on.

This is usually Gem::Platform::RUBY or Gem::Platform::CURRENT.

Most gems contain pure Ruby code; they should simply leave the default value in place. Some gems contain C (or other) code to be compiled into a Ruby “extension”. The should leave the default value in place unless their code will only compile on a certain type of system. Some gems consist of pre-compiled code (“binary gems”). It's especially important that they set the platform attribute appropriately. A shortcut is to set the platform to Gem::Platform::CURRENT, which will cause the gem builder to set the platform to the appropriate value for the system on which the build is being performed.

If this attribute is set to a non-default value, it will be included in the filename of the gem when it is built such as: nokogiri-1.6.0-x86-mingw32.gem

Usage:

spec.platform = Gem::Platform.local
# File lib/rubygems/specification.rb, line 247
def platform= platform
  if @original_platform.nil? or
     @original_platform == Gem::Platform::RUBY then
    @original_platform = platform
  end

  case platform
  when Gem::Platform::CURRENT then
    @new_platform = Gem::Platform.local
    @original_platform = @new_platform.to_s

  when Gem::Platform then
    @new_platform = platform

  # legacy constants
  when nil, Gem::Platform::RUBY then
    @new_platform = Gem::Platform::RUBY
  when 'mswin32' then # was Gem::Platform::WIN32
    @new_platform = Gem::Platform.new 'x86-mswin32'
  when 'i586-linux' then # was Gem::Platform::LINUX_586
    @new_platform = Gem::Platform.new 'x86-linux'
  when 'powerpc-darwin' then # was Gem::Platform::DARWIN
    @new_platform = Gem::Platform.new 'ppc-darwin'
  else
    @new_platform = Gem::Platform.new platform
  end

  @platform = @new_platform.to_s

  invalidate_memoized_attributes

  @new_platform
end

Specification internals

↑ top

Constants

DateTimeFormat

Attributes

activated[RW]

True when this gemspec has been activated. This attribute is not persisted.

activated?[RW]

True when this gemspec has been activated. This attribute is not persisted.

default_executable[W]

Sets the default executable for this gem.

Deprecated: You must now specify the executable name to Gem.bin_path.

loaded_from[R]

Path this gemspec was loaded from. This attribute is not persisted.

required_ruby_version[R]

The version of ruby required by this gem

required_rubygems_version[R]

The RubyGems version required by this gem

rubyforge_project[RW]

The rubyforge project this gem lives under. i.e. RubyGems' #rubyforge_project is “rubygems”.

This option is deprecated.

specification_version[RW]

The Gem::Specification version of this gemspec.

Do not set this, it is set automatically when the gem is packaged.

Public Class Methods

_load(str) click to toggle source

Load custom marshal format, re-initializing defaults as needed

# File lib/rubygems/specification.rb, line 1076
def self._load(str)
  array = Marshal.load str

  spec = Gem::Specification.new
  spec.instance_variable_set :@specification_version, array[1]

  current_version = CURRENT_SPECIFICATION_VERSION

  field_count = if spec.specification_version > current_version then
                  spec.instance_variable_set :@specification_version,
                                             current_version
                  MARSHAL_FIELDS[current_version]
                else
                  MARSHAL_FIELDS[spec.specification_version]
                end

  if array.size < field_count then
    raise TypeError, "invalid Gem::Specification format #{array.inspect}"
  end

  # Cleanup any YAML::PrivateType. They only show up for an old bug
  # where nil => null, so just convert them to nil based on the type.

  array.map! { |e| e.kind_of?(YAML::PrivateType) ? nil : e }

  spec.instance_variable_set :@rubygems_version,          array[0]
  # spec version
  spec.instance_variable_set :@name,                      array[2]
  spec.instance_variable_set :@version,                   array[3]
  spec.date =                                             array[4]
  spec.instance_variable_set :@summary,                   array[5]
  spec.instance_variable_set :@required_ruby_version,     array[6]
  spec.instance_variable_set :@required_rubygems_version, array[7]
  spec.instance_variable_set :@original_platform,         array[8]
  spec.instance_variable_set :@dependencies,              array[9]
  spec.instance_variable_set :@rubyforge_project,         array[10]
  spec.instance_variable_set :@email,                     array[11]
  spec.instance_variable_set :@authors,                   array[12]
  spec.instance_variable_set :@description,               array[13]
  spec.instance_variable_set :@homepage,                  array[14]
  spec.instance_variable_set :@has_rdoc,                  array[15]
  spec.instance_variable_set :@new_platform,              array[16]
  spec.instance_variable_set :@platform,                  array[16].to_s
  spec.instance_variable_set :@license,                   array[17]
  spec.instance_variable_set :@metadata,                  array[18]
  spec.instance_variable_set :@loaded,                    false
  spec.instance_variable_set :@activated,                 false

  spec
end
add_spec(spec) click to toggle source

Adds spec to the known specifications, keeping the collection properly sorted.

# File lib/rubygems/specification.rb, line 706
def self.add_spec spec
  # TODO: find all extraneous adds
  # puts
  # p :add_spec => [spec.full_name, caller.reject { |s| s =~ /minitest/ }]

  # TODO: flush the rest of the crap from the tests
  # raise "no dupes #{spec.full_name} in #{all_names.inspect}" if
  #   _all.include? spec

  raise "nil spec!" unless spec # TODO: remove once we're happy with tests

  return if _all.include? spec

  _all << spec
  _resort!
end
add_specs(*specs) click to toggle source

Adds multiple specs to the known specifications.

# File lib/rubygems/specification.rb, line 726
def self.add_specs *specs
  raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy

  # TODO: this is much more efficient, but we need the extra checks for now
  # _all.concat specs
  # _resort!

  specs.each do |spec| # TODO: slow
    add_spec spec
  end
end
all() click to toggle source

Returns all specifications. This method is discouraged from use. You probably want to use one of the Enumerable methods instead.

# File lib/rubygems/specification.rb, line 742
def self.all
  warn "NOTE: Specification.all called from #{caller.first}" unless
    Gem::Deprecate.skip
  _all
end
all=(specs) click to toggle source

Sets the known specs to specs. Not guaranteed to work for you in the future. Use at your own risk. Caveat emptor. Doomy doom doom. Etc etc.

# File lib/rubygems/specification.rb, line 760
def self.all= specs
  @@all = specs
end
all_names() click to toggle source

Return full names of all specs in sorted order.

# File lib/rubygems/specification.rb, line 767
def self.all_names
  self._all.map(&:full_name)
end
array_attributes() click to toggle source

Return the list of all array-oriented instance variables.

# File lib/rubygems/specification.rb, line 776
def self.array_attributes
  @@array_attributes.dup
end
attribute_names() click to toggle source

Return the list of all instance variables.

# File lib/rubygems/specification.rb, line 785
def self.attribute_names
  @@attributes.dup
end
default_specifications_dir() click to toggle source
# File lib/rubygems/specification.rb, line 636
def default_specifications_dir
  File.join(Gem.default_dir, "specifications", "default")
end
dirs() click to toggle source

Return the directories that Specification uses to find specs.

# File lib/rubygems/specification.rb, line 792
def self.dirs
  @@dirs ||= Gem.path.collect { |dir|
    File.join dir.dup.untaint, "specifications"
  }
end
dirs=(dirs) click to toggle source

Set the directories that Specification uses to find specs. Setting this resets the list of known specs.

# File lib/rubygems/specification.rb, line 802
def self.dirs= dirs
  # TODO: find extra calls to dir=
  # warn "NOTE: dirs= called from #{caller.first} for #{dirs.inspect}"

  self.reset

  # ugh
  @@dirs = Array(dirs).map { |dir| File.join dir, "specifications" }
end
each() { |x| ... } click to toggle source

Enumerate every known spec. See ::dirs= and ::add_spec to set the list of specs.

# File lib/rubygems/specification.rb, line 818
def self.each
  return enum_for(:each) unless block_given?

  self._all.each do |x|
    yield x
  end
end
find_all_by_name(name, *requirements) click to toggle source

Returns every spec that matches name and optional requirements.

# File lib/rubygems/specification.rb, line 829
def self.find_all_by_name name, *requirements
  requirements = Gem::Requirement.default if requirements.empty?

  # TODO: maybe try: find_all { |s| spec === dep }

  Gem::Dependency.new(name, *requirements).matching_specs
end
find_by_name(name, *requirements) click to toggle source

Find the best specification matching a name and requirements. Raises if the dependency doesn't resolve to a valid specification.

# File lib/rubygems/specification.rb, line 841
def self.find_by_name name, *requirements
  requirements = Gem::Requirement.default if requirements.empty?

  # TODO: maybe try: find { |s| spec === dep }

  Gem::Dependency.new(name, *requirements).to_spec
end
find_by_path(path) click to toggle source

Return the best specification that contains the file matching path.

# File lib/rubygems/specification.rb, line 852
def self.find_by_path path
  self.find { |spec|
    spec.contains_requirable_file? path
  }
end
find_in_unresolved(path) click to toggle source

Return currently unresolved specs that contain the file matching path.

# File lib/rubygems/specification.rb, line 871
def self.find_in_unresolved path
  # TODO: do we need these?? Kill it
  specs = unresolved_deps.values.map { |dep| dep.to_specs }.flatten

  specs.find_all { |spec| spec.contains_requirable_file? path }
end
find_in_unresolved_tree(path) click to toggle source

Search through all unresolved deps and sub-dependencies and return specs that contain the file matching path.

# File lib/rubygems/specification.rb, line 882
def self.find_in_unresolved_tree path
  specs = unresolved_deps.values.map { |dep| dep.to_specs }.flatten

  specs.reverse_each do |spec|
    trails = []
    spec.traverse do |from_spec, dep, to_spec, trail|
      next unless to_spec.conflicts.empty?
      trails << trail if to_spec.contains_requirable_file? path
    end

    next if trails.empty?

    return trails.map(&:reverse).sort.first.reverse
  end

  []
end
find_inactive_by_path(path) click to toggle source

Return the best specification that contains the file matching path amongst the specs that are not activated.

# File lib/rubygems/specification.rb, line 862
def self.find_inactive_by_path path
  self.find { |spec|
    spec.contains_requirable_file? path unless spec.activated?
  }
end
from_yaml(input) click to toggle source

Special loader for YAML files. When a Specification object is loaded from a YAML file, it bypasses the normal Ruby object initialization routine (initialize). This method makes up for that and deals with gems of different ages.

input can be anything that YAML.load() accepts: String or IO.

# File lib/rubygems/specification.rb, line 908
def self.from_yaml(input)
  Gem.load_yaml

  input = normalize_yaml_input input
  spec = YAML.load input

  if spec && spec.class == FalseClass then
    raise Gem::EndOfYAMLException
  end

  unless Gem::Specification === spec then
    raise Gem::Exception, "YAML data doesn't evaluate to gem specification"
  end

  spec.specification_version ||= NONEXISTENT_SPECIFICATION_VERSION
  spec.reset_nil_attributes_to_default

  spec
end
latest_specs(prerelease = false) click to toggle source

Return the latest specs, optionally including prerelease specs if prerelease is true.

# File lib/rubygems/specification.rb, line 932
def self.latest_specs prerelease = false
  result = Hash.new { |h,k| h[k] = {} }
  native = {}

  Gem::Specification.reverse_each do |spec|
    next if spec.version.prerelease? unless prerelease

    native[spec.name] = spec.version if spec.platform == Gem::Platform::RUBY
    result[spec.name][spec.platform] = spec
  end

  result.map(&:last).map(&:values).flatten.reject { |spec|
    minimum = native[spec.name]
    minimum && spec.version < minimum
  }
end
load(file) click to toggle source

Loads Ruby format gemspec from file.

# File lib/rubygems/specification.rb, line 952
def self.load file
  return unless file
  file = file.dup.untaint
  return unless File.file?(file)

  code = if defined? Encoding
           File.read file, :mode => 'r:UTF-8:-'
         else
           File.read file
         end

  code.untaint

  begin
    spec = eval code, binding, file

    if Gem::Specification === spec
      spec.loaded_from = file.to_s
      return spec
    end

    warn "[#{file}] isn't a Gem::Specification (#{spec.class} instead)."
  rescue SignalException, SystemExit
    raise
  rescue SyntaxError, Exception => e
    warn "Invalid gemspec in [#{file}]: #{e}"
  end

  nil
end
load_defaults() click to toggle source

Loads the default specifications. It should be called only once.

# File lib/rubygems/specification.rb, line 696
def self.load_defaults
  each_default do |spec|
    Gem.register_default_spec(spec)
  end
end
new(name = nil, version = nil) { |self| ... } click to toggle source

Specification constructor. Assigns the default values to the attributes and yields itself for further initialization. Optionally takes name and version.

# File lib/rubygems/specification.rb, line 1738
def initialize name = nil, version = nil
  @loaded = false
  @activated = false
  @loaded_from = nil
  @original_platform = nil

  @@nil_attributes.each do |key|
    instance_variable_set "@#{key}", nil
  end

  @@non_nil_attributes.each do |key|
    default = default_value(key)
    value = case default
            when Time, Numeric, Symbol, true, false, nil then default
            else default.dup
            end

    instance_variable_set "@#{key}", value
  end

  @new_platform = Gem::Platform::RUBY

  self.name = name if name
  self.version = version if version

  yield self if block_given?
end
non_nil_attributes() click to toggle source

Specification attributes that must be non-nil

# File lib/rubygems/specification.rb, line 986
def self.non_nil_attributes
  @@non_nil_attributes.dup
end
normalize_yaml_input(input) click to toggle source

Make sure the YAML specification is properly formatted with dashes

# File lib/rubygems/specification.rb, line 993
def self.normalize_yaml_input(input)
  result = input.respond_to?(:read) ? input.read : input
  result = "--- " + result unless result =~ /\A--- /
  result.gsub!(/ !!null \n/, " \n")
  # date: 2011-04-26 00:00:00.000000000Z
  # date: 2011-04-26 00:00:00.000000000 Z
  result.gsub!(/^(date: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+?)Z/, '\1 Z')
  result
end
outdated() click to toggle source

Return a list of all outdated specifications. This method is HEAVY as it must go fetch specifications from the server.

# File lib/rubygems/specification.rb, line 1007
def self.outdated
  outdateds = []

  # TODO: maybe we should switch to rubygems' version service?
  fetcher = Gem::SpecFetcher.fetcher

  latest_specs(true).each do |local|
    dependency = Gem::Dependency.new local.name, ">= #{local.version}"
    remotes, _   = fetcher.search_for_dependency dependency
    remotes      = remotes.map { |n, _| n.version }
    latest       = remotes.sort.last

    outdateds << local.name if latest and local.version < latest
  end

  outdateds
end
remove_spec(spec) click to toggle source

Removes spec from the known specs.

# File lib/rubygems/specification.rb, line 1028
def self.remove_spec spec
  _all.delete spec
end
required_attribute?(name) click to toggle source

Is name a required attribute?

# File lib/rubygems/specification.rb, line 1035
def self.required_attribute?(name)
  @@required_attributes.include? name.to_sym
end
required_attributes() click to toggle source

Required specification attributes

# File lib/rubygems/specification.rb, line 1042
def self.required_attributes
  @@required_attributes.dup
end
reset() click to toggle source

Reset the list of known specs, running pre and post reset hooks registered in Gem.

# File lib/rubygems/specification.rb, line 1050
def self.reset
  @@dirs = nil
  Gem.pre_reset_hooks.each { |hook| hook.call }
  @@all = nil
  unresolved = unresolved_deps
  unless unresolved.empty? then
    w = "W" + "ARN"
    warn "#{w}: Unresolved specs during Gem::Specification.reset:"
    unresolved.values.each do |dep|
      warn "      #{dep}"
    end
    warn "#{w}: Clearing out unresolved specs."
    warn "Please report a bug if this causes problems."
    unresolved.clear
  end
  Gem.post_reset_hooks.each { |hook| hook.call }
end
unresolved_deps() click to toggle source

DOC: This method needs documented or nodoc'd

# File lib/rubygems/specification.rb, line 1069
def self.unresolved_deps
  @unresolved_deps ||= Hash.new { |h, n| h[n] = Gem::Dependency.new n }
end

Public Instance Methods

_dump(limit) click to toggle source

Dump only crucial instance variables.

# File lib/rubygems/specification.rb, line 1144
def _dump(limit)
  Marshal.dump [
    @rubygems_version,
    @specification_version,
    @name,
    @version,
    date,
    @summary,
    @required_ruby_version,
    @required_rubygems_version,
    @original_platform,
    @dependencies,
    @rubyforge_project,
    @email,
    @authors,
    @description,
    @homepage,
    true, # has_rdoc
    @new_platform,
    @licenses,
    @metadata
  ]
end
activate() click to toggle source

Activate this spec, registering it as a loaded spec and adding it's lib paths to $LOAD_PATH. Returns true if the spec was activated, false if it was previously activated. Freaks out if there are conflicts upon activation.

# File lib/rubygems/specification.rb, line 1174
def activate
  raise_if_conflicts

  return false if Gem.loaded_specs[self.name]

  activate_dependencies
  add_self_to_load_path

  Gem.loaded_specs[self.name] = self
  @activated = true
  @loaded = true

  return true
end
activate_dependencies() click to toggle source

Activate all unambiguously resolved runtime dependencies of this spec. Add any ambigous dependencies to the unresolved list to be resolved later, as needed.

# File lib/rubygems/specification.rb, line 1194
def activate_dependencies
  unresolved = Gem::Specification.unresolved_deps

  self.runtime_dependencies.each do |spec_dep|
    if loaded = Gem.loaded_specs[spec_dep.name]
      next if spec_dep.matches_spec? loaded

      msg = "can't satisfy '#{spec_dep}', already activated '#{loaded.full_name}'"
      e = Gem::LoadError.new msg
      e.name = spec_dep.name

      raise e
    end

    specs = spec_dep.to_specs

    if specs.size == 1 then
      specs.first.activate
    else
      name = spec_dep.name
      unresolved[name] = unresolved[name].merge spec_dep
    end
  end

  unresolved.delete self.name
end
add_bindir(executables) click to toggle source

Returns an array with bindir attached to each executable in the executables list

# File lib/rubygems/specification.rb, line 1225
def add_bindir(executables)
  return nil if executables.nil?

  if @bindir then
    Array(executables).map { |e| File.join(@bindir, e) }
  else
    executables
  end
rescue
  return nil
end
add_dependency(gem, *requirements) click to toggle source
Alias for: add_runtime_dependency
add_self_to_load_path() click to toggle source

Adds this spec's require paths to LOAD_PATH, in the proper location.

# File lib/rubygems/specification.rb, line 1264
def add_self_to_load_path
  return if default_gem?

  paths = require_paths.map do |path|
    File.join full_gem_path, path
  end

  # gem directories must come after -I and ENV['RUBYLIB']
  insert_index = Gem.load_path_insert_index

  if insert_index then
    # gem directories must come after -I and ENV['RUBYLIB']
    $LOAD_PATH.insert(insert_index, *paths)
  else
    # we are probably testing in core, -I and RUBYLIB don't apply
    $LOAD_PATH.unshift(*paths)
  end
end
author() click to toggle source

Singular reader for authors. Returns the first author in the list

# File lib/rubygems/specification.rb, line 1286
def author
  val = authors and val.first
end
authors() click to toggle source

The list of author names who wrote this gem.

spec.authors = ['Chad Fowler', 'Jim Weirich', 'Rich Kilmer']
# File lib/rubygems/specification.rb, line 1295
def authors
  @authors ||= []
end
base_dir() click to toggle source

Returns the full path to the base gem directory.

eg: /usr/local/lib/ruby/gems/1.8

# File lib/rubygems/specification.rb, line 1304
def base_dir
  return Gem.dir unless loaded_from
  @base_dir ||= if default_gem? then
                  File.dirname File.dirname File.dirname loaded_from
                else
                  File.dirname File.dirname loaded_from
                end
end
bin_dir() click to toggle source

Returns the full path to installed gem's bin directory.

NOTE: do not confuse this with bindir, which is just 'bin', not a full path.

# File lib/rubygems/specification.rb, line 1319
def bin_dir
  @bin_dir ||= File.join gem_dir, bindir # TODO: this is unfortunate
end
bin_file(name) click to toggle source

Returns the full path to an executable named name in this gem.

# File lib/rubygems/specification.rb, line 1326
def bin_file name
  File.join bin_dir, name
end
build_args() click to toggle source

Returns the #build_args used to install the gem

# File lib/rubygems/specification.rb, line 1333
def build_args
  if File.exists? build_info_file
    File.readlines(build_info_file).map { |x| x.strip }
  else
    []
  end
end
build_info_dir() click to toggle source

Returns the full path to the build info directory

# File lib/rubygems/specification.rb, line 1344
def build_info_dir
  File.join base_dir, "build_info"
end
build_info_file() click to toggle source

Returns the full path to the file containing the build information generated when the gem was installed

# File lib/rubygems/specification.rb, line 1352
def build_info_file
  File.join build_info_dir, "#{full_name}.info"
end
cache_dir() click to toggle source

Returns the full path to the cache directory containing this spec's cached gem.

# File lib/rubygems/specification.rb, line 1360
def cache_dir
  @cache_dir ||= File.join base_dir, "cache"
end
cache_file() click to toggle source

Returns the full path to the cached gem for this spec.

# File lib/rubygems/specification.rb, line 1367
def cache_file
  @cache_file ||= File.join cache_dir, "#{full_name}.gem"
end
conflicts() click to toggle source

Return any possible conflicts against the currently loaded specs.

# File lib/rubygems/specification.rb, line 1374
def conflicts
  conflicts = {}
  Gem.loaded_specs.values.each do |spec|
    bad = self.runtime_dependencies.find_all { |dep|
      spec.name == dep.name and not spec.satisfies_requirement? dep
    }

    conflicts[spec] = bad unless bad.empty?
  end
  conflicts
end
contains_requirable_file?(file) click to toggle source

Return true if this spec can require file.

# File lib/rubygems/specification.rb, line 1389
def contains_requirable_file? file
  root     = full_gem_path
  suffixes = Gem.suffixes

  require_paths.any? do |lib|
    base = "#{root}/#{lib}/#{file}"
    suffixes.any? { |suf| File.file? "#{base}#{suf}" }
  end
end
date() click to toggle source

The date this gem was created. Lazily defaults to the current UTC date.

There is no need to set this in your gem specification.

# File lib/rubygems/specification.rb, line 1404
def date
  @date ||= TODAY
end
date=(date) click to toggle source

The date this gem was created

DO NOT set this, it is set automatically when the gem is packaged.

# File lib/rubygems/specification.rb, line 1418
def date= date
  # We want to end up with a Time object with one-day resolution.
  # This is the cleanest, most-readable, faster-than-using-Date
  # way to do it.
  @date = case date
          when String then
            if DateTimeFormat =~ date then
              Time.utc($1.to_i, $2.to_i, $3.to_i)

            # Workaround for where the date format output from psych isn't
            # parsed as a Time object by syck and thus comes through as a
            # string.
            elsif /\A(\d{4})-(\d{2})-(\d{2}) \d{2}:\d{2}:\d{2}\.\d+?Z\z/ =~ date then
              Time.utc($1.to_i, $2.to_i, $3.to_i)
            else
              raise(Gem::InvalidSpecificationException,
                    "invalid date format in specification: #{date.inspect}")
            end
          when Time, Date then
            Time.utc(date.year, date.month, date.day)
          else
            TODAY
          end
end
default_gem?() click to toggle source
# File lib/rubygems/specification.rb, line 2580
def default_gem?
  loaded_from &&
    File.dirname(loaded_from) == self.class.default_specifications_dir
end
default_value(name) click to toggle source

The default value for specification attribute name

# File lib/rubygems/specification.rb, line 1463
def default_value name
  @@default_value[name]
end
dependencies() click to toggle source

A list of Gem::Dependency objects this gem depends on.

Use add_dependency or add_development_dependency to add dependencies to a gem.

# File lib/rubygems/specification.rb, line 1473
def dependencies
  @dependencies ||= []
end
dependent_gems() click to toggle source

Return a list of all gems that have a dependency on this gemspec. The list is structured with entries that conform to:

[depending_gem, dependency, [list_of_gems_that_satisfy_dependency]]
# File lib/rubygems/specification.rb, line 1483
def dependent_gems
  # REFACTOR: out = []; each; out; ? Really? No #collect love?
  out = []
  Gem::Specification.each do |spec|
    spec.dependencies.each do |dep|
      if self.satisfies_requirement?(dep) then
        sats = []
        find_all_satisfiers(dep) do |sat|
          sats << sat
        end
        out << [spec, dep, sats]
      end
    end
  end
  out
end
dependent_specs() click to toggle source

Returns all specs that matches this spec's runtime dependencies.

# File lib/rubygems/specification.rb, line 1503
def dependent_specs
  runtime_dependencies.map { |dep| dep.to_specs }.flatten
end
description=(str) click to toggle source

A detailed description of this gem. See also summary

# File lib/rubygems/specification.rb, line 1510
def description= str
  @description = str.to_s
end
development_dependencies() click to toggle source

List of dependencies that are used for development

# File lib/rubygems/specification.rb, line 1517
def development_dependencies
  dependencies.select { |d| d.type == :development }
end
doc_dir(type = nil) click to toggle source

Returns the full path to this spec's documentation directory. If type is given it will be appended to the end. For examlpe:

spec.doc_dir      # => "/path/to/gem_repo/doc/a-1"

spec.doc_dir 'ri' # => "/path/to/gem_repo/doc/a-1/ri"

# File lib/rubygems/specification.rb, line 1529
def doc_dir type = nil
  @doc_dir ||= File.join base_dir, 'doc', full_name

  if type then
    File.join @doc_dir, type
  else
    @doc_dir
  end
end
executable() click to toggle source

Singular accessor for executables

# File lib/rubygems/specification.rb, line 1567
def executable
  val = executables and val.first
end
executable=(o) click to toggle source

Singular accessor for executables

# File lib/rubygems/specification.rb, line 1574
def executable=o
  self.executables = [o]
end
executables=(value) click to toggle source

Sets executables to value, ensuring it is an array. Don't use this, push onto the array instead.

# File lib/rubygems/specification.rb, line 1582
def executables= value
  # TODO: warn about setting instead of pushing
  @executables = Array(value)
end
extensions=(extensions) click to toggle source

Sets extensions to extensions, ensuring it is an array. Don't use this, push onto the array instead.

# File lib/rubygems/specification.rb, line 1591
def extensions= extensions
  # TODO: warn about setting instead of pushing
  @extensions = Array extensions
end
extra_rdoc_files=(files) click to toggle source

Sets #extra_rdoc_files to files, ensuring it is an array. Don't use this, push onto the array instead.

# File lib/rubygems/specification.rb, line 1600
def extra_rdoc_files= files
  # TODO: warn about setting instead of pushing
  @extra_rdoc_files = Array files
end
file_name() click to toggle source

The default (generated) file name of the gem. See also spec_name.

spec.file_name # => "example-1.0.gem"

# File lib/rubygems/specification.rb, line 1610
def file_name
  "#{full_name}.gem"
end
files=(files) click to toggle source

Sets files to files, ensuring it is an array.

# File lib/rubygems/specification.rb, line 1617
def files= files
  @files = Array files
end
for_cache() click to toggle source

Creates a duplicate spec without large blobs that aren't used at runtime.

# File lib/rubygems/specification.rb, line 1635
def for_cache
  spec = dup

  spec.files = nil
  spec.test_files = nil

  spec
end
full_gem_path() click to toggle source

The full path to the gem (install path + full name).

# File lib/rubygems/specification.rb, line 1647
def full_gem_path
  # TODO: This is a heavily used method by gems, so we'll need
  # to aleast just alias it to #gem_dir rather than remove it.

  # TODO: also, shouldn't it default to full_name if it hasn't been written?
  return @full_gem_path if defined?(@full_gem_path) && @full_gem_path

  @full_gem_path = File.expand_path File.join(gems_dir, full_name)
  @full_gem_path.untaint

  return @full_gem_path if File.directory? @full_gem_path

  @full_gem_path = File.expand_path File.join(gems_dir, original_name)
end
full_name() click to toggle source

Returns the full name (name-version) of this Gem. Platform information is included (name-version-platform) if it is specified and not the default Ruby platform.

# File lib/rubygems/specification.rb, line 1667
def full_name
  @full_name ||= if platform == Gem::Platform::RUBY or platform.nil? then
                   "#{@name}-#{@version}".untaint
                 else
                   "#{@name}-#{@version}-#{platform}".untaint
                 end
end
gem_dir() click to toggle source

Returns the full path to this spec's gem directory. eg: /usr/local/lib/ruby/1.8/gems/mygem-1.0

# File lib/rubygems/specification.rb, line 1679
def gem_dir
  @gem_dir ||= File.expand_path File.join(gems_dir, full_name)
end
gems_dir() click to toggle source

Returns the full path to the gems directory containing this spec's gem directory. eg: /usr/local/lib/ruby/1.8/gems

# File lib/rubygems/specification.rb, line 1687
def gems_dir
  # TODO: this logic seems terribly broken, but tests fail if just base_dir
  @gems_dir ||= File.join(loaded_from && base_dir || Gem.dir, "gems")
end
has_unit_tests?() click to toggle source

True if this gem has files in #test_files

# File lib/rubygems/specification.rb, line 1715
def has_unit_tests?
  not test_files.empty?
end
initialize_copy(other_spec) click to toggle source

Duplicates ::array_attributes from other_spec so state isn't shared.

# File lib/rubygems/specification.rb, line 1769
def initialize_copy other_spec
  self.class.array_attributes.each do |name|
    name = :"@#{name}"
    next unless other_spec.instance_variable_defined? name

    begin
      val = other_spec.instance_variable_get(name)
      if val then
        instance_variable_set name, val.dup
      elsif Gem.configuration.really_verbose
        warn "WARNING: #{full_name} has an invalid nil value for #{name}"
      end
    rescue TypeError
      e = Gem::FormatException.new            "#{full_name} has an invalid value for #{name}"

      e.file_path = loaded_from
      raise e
    end
  end
end
inspect() click to toggle source
# File lib/rubygems/specification.rb, line 1802
def inspect
  if $DEBUG
    super
  else
    "#<#{self.class}:0x#{__id__.to_s(16)} #{full_name}>"
  end
end
lib_dirs_glob() click to toggle source

Returns a string usable in Dir.glob to match all requirable paths for this spec.

# File lib/rubygems/specification.rb, line 1814
def lib_dirs_glob
  dirs = if self.require_paths.size > 1 then
           "{#{self.require_paths.join(',')}}"
         else
           self.require_paths.first
         end

  "#{self.full_gem_path}/#{dirs}"
end
lib_files() click to toggle source

Files in the Gem under one of the #require_paths

# File lib/rubygems/specification.rb, line 1827
def lib_files
  @files.select do |file|
    require_paths.any? do |path|
      file.start_with? path
    end
  end
end
license() click to toggle source

Singular accessor for licenses

# File lib/rubygems/specification.rb, line 1838
def license
  val = licenses and val.first
end
licenses() click to toggle source

Plural accessor for setting licenses

# File lib/rubygems/specification.rb, line 1845
def licenses
  @licenses ||= []
end
loaded_from=(path) click to toggle source

Set the location a Specification was loaded from. obj is converted to a String.

# File lib/rubygems/specification.rb, line 1853
def loaded_from= path
  @loaded_from   = path.to_s

  # reset everything @loaded_from depends upon
  @base_dir      = nil
  @bin_dir       = nil
  @cache_dir     = nil
  @cache_file    = nil
  @doc_dir       = nil
  @full_gem_path = nil
  @gem_dir       = nil
  @gems_dir      = nil
  @ri_dir        = nil
  @spec_dir      = nil
  @spec_file     = nil
end
mark_version() click to toggle source

Sets the #rubygems_version to the current RubyGems version.

# File lib/rubygems/specification.rb, line 1873
def mark_version
  @rubygems_version = Gem::VERSION
end
matches_for_glob(glob) click to toggle source

Return all files in this gem that match for glob.

# File lib/rubygems/specification.rb, line 1880
def matches_for_glob glob # TODO: rename?
  # TODO: do we need these?? Kill it
  glob = File.join(self.lib_dirs_glob, glob)

  Dir[glob].map { |f| f.untaint } # FIX our tests are broken, run w/ SAFE=1
end
name_tuple() click to toggle source

Return a NameTuple that represents this Specification

# File lib/rubygems/specification.rb, line 1922
def name_tuple
  Gem::NameTuple.new name, version, original_platform
end
normalize() click to toggle source

Normalize the list of files so that:

  • All file lists have redundancies removed.

  • Files referenced in the #extra_rdoc_files are included in the package file list.

# File lib/rubygems/specification.rb, line 1905
def normalize
  if defined?(@extra_rdoc_files) and @extra_rdoc_files then
    @extra_rdoc_files.uniq!
    @files ||= []
    @files.concat(@extra_rdoc_files)
  end

  @files            = @files.uniq if @files
  @extensions       = @extensions.uniq if @extensions
  @test_files       = @test_files.uniq if @test_files
  @executables      = @executables.uniq if @executables
  @extra_rdoc_files = @extra_rdoc_files.uniq if @extra_rdoc_files
end
platform() click to toggle source

The platform this gem runs on. See Gem::Platform for details.

# File lib/rubygems/specification.rb, line 1948
def platform
  @new_platform ||= Gem::Platform::RUBY
end
raise_if_conflicts() click to toggle source

Check the spec for possible conflicts and freak out if there are any.

# File lib/rubygems/specification.rb, line 1981
def raise_if_conflicts
  other = Gem.loaded_specs[self.name]

  if other and self.version != other.version then
    # This gem is already loaded.  If the currently loaded gem is not in the
    # list of candidate gems, then we have a version conflict.

    msg = "can't activate #{full_name}, already activated #{other.full_name}"

    e = Gem::LoadError.new msg
    e.name = self.name
    # TODO: e.requirement = dep.requirement

    raise e
  end

  conf = self.conflicts

  unless conf.empty? then
    y = conf.map { |act,con|
      "#{act.full_name} conflicts with #{con.join(", ")}"
    }.join ", "

    # TODO: improve message by saying who activated `con`

    raise Gem::LoadError, "Unable to activate #{self.full_name}, because #{y}"
  end
end
rdoc_options=(options) click to toggle source

Sets #rdoc_options to value, ensuring it is an array. Don't use this, push onto the array instead.

# File lib/rubygems/specification.rb, line 2014
def rdoc_options= options
  # TODO: warn about setting instead of pushing
  @rdoc_options = Array options
end
require_path() click to toggle source

Singular accessor for require_paths

# File lib/rubygems/specification.rb, line 2022
def require_path
  val = require_paths and val.first
end
require_path=(path) click to toggle source

Singular accessor for require_paths

# File lib/rubygems/specification.rb, line 2029
def require_path= path
  self.require_paths = [path]
end
required_rubygems_version=(req) click to toggle source

The RubyGems version required by this gem

# File lib/rubygems/specification.rb, line 2036
def required_rubygems_version= req
  @required_rubygems_version = Gem::Requirement.create req
end
requirements=(req) click to toggle source

Set requirements to req, ensuring it is an array. Don't use this, push onto the array instead.

# File lib/rubygems/specification.rb, line 2044
def requirements= req
  # TODO: warn about setting instead of pushing
  @requirements = Array req
end
reset_nil_attributes_to_default() click to toggle source

Reset nil attributes to their default values to make the spec valid

# File lib/rubygems/specification.rb, line 2563
def reset_nil_attributes_to_default
  nil_attributes = self.class.non_nil_attributes.find_all do |name|
    !instance_variable_defined?("@#{name}") || instance_variable_get("@#{name}").nil?
  end

  nil_attributes.each do |attribute|
    default = self.default_value attribute

    value = case default
            when Time, Numeric, Symbol, true, false, nil then default
            else default.dup
            end

    instance_variable_set "@#{attribute}", value
  end
end
ri_dir() click to toggle source

Returns the full path to this spec's ri directory.

# File lib/rubygems/specification.rb, line 2052
def ri_dir
  @ri_dir ||= File.join base_dir, 'ri', full_name
end
runtime_dependencies() click to toggle source

List of dependencies that will automatically be activated at runtime.

# File lib/rubygems/specification.rb, line 2085
def runtime_dependencies
  dependencies.select { |d| d.type == :runtime }
end
satisfies_requirement?(dependency) click to toggle source

Checks if this specification meets the requirement of dependency.

# File lib/rubygems/specification.rb, line 2101
def satisfies_requirement? dependency
  return @name == dependency.name &&
    dependency.requirement.satisfied_by?(@version)
end
sort_obj() click to toggle source

Returns an object you can use to sort specifications in sort_by.

# File lib/rubygems/specification.rb, line 2109
def sort_obj
  # TODO: this is horrible. Deprecate it.
  [@name, @version, @new_platform == Gem::Platform::RUBY ? -1 : 1]
end
spec_dir() click to toggle source

Returns the full path to the directory containing this spec's gemspec file. eg: /usr/local/lib/ruby/gems/1.8/specifications

# File lib/rubygems/specification.rb, line 2118
def spec_dir
  @spec_dir ||= File.join base_dir, "specifications"
end
spec_file() click to toggle source

Returns the full path to this spec's gemspec file. eg: /usr/local/lib/ruby/gems/1.8/specifications/mygem-1.0.gemspec

# File lib/rubygems/specification.rb, line 2126
def spec_file
  @spec_file ||= File.join spec_dir, "#{full_name}.gemspec"
end
spec_name() click to toggle source

The default name of the gemspec. See also file_name

spec.spec_name # => "example-1.0.gemspec"

# File lib/rubygems/specification.rb, line 2135
def spec_name
  "#{full_name}.gemspec"
end
summary=(str) click to toggle source

A short summary of this gem's description.

# File lib/rubygems/specification.rb, line 2142
def summary= str
  @summary = str.to_s.strip.
    gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').gsub(/\n[ \t]*/, " ") # so. weird.
end
test_file() click to toggle source

Singular accessor for test_files

# File lib/rubygems/specification.rb, line 2150
def test_file
  val = test_files and val.first
end
test_file=(file) click to toggle source

Singular mutator for test_files

# File lib/rubygems/specification.rb, line 2157
def test_file= file
  self.test_files = [file]
end
test_files() click to toggle source

Test files included in this gem. You cannot append to this accessor, you must assign to it.

# File lib/rubygems/specification.rb, line 2165
def test_files
  # Handle the possibility that we have @test_suite_file but not
  # @test_files.  This will happen when an old gem is loaded via
  # YAML.
  if defined? @test_suite_file then
    @test_files = [@test_suite_file].flatten
    @test_suite_file = nil
  end
  if defined?(@test_files) and @test_files then
    @test_files
  else
    @test_files = []
  end
end
to_ruby() click to toggle source

Returns a Ruby code representation of this specification, such that it can be eval'ed and reconstruct the same specification later. Attributes that still have their default values are omitted.

REFACTOR: This, plus stuff like ruby_code and pretty_print, should probably be extracted out into some sort of separate class. SRP, do you speak it!??!

# File lib/rubygems/specification.rb, line 2189
def to_ruby
  mark_version
  result = []
  result << "# -*- encoding: utf-8 -*-"
  result << nil
  result << "Gem::Specification.new do |s|"

  result << "  s.name = #{ruby_code name}"
  result << "  s.version = #{ruby_code version}"
  unless platform.nil? or platform == Gem::Platform::RUBY then
    result << "  s.platform = #{ruby_code original_platform}"
  end
  result << ""
  result << "  s.required_rubygems_version = #{ruby_code required_rubygems_version} if s.respond_to? :required_rubygems_version="

  if metadata and !metadata.empty?
    result << "  s.metadata = #{ruby_code metadata} if s.respond_to? :metadata="
  end

  handled = [
    :dependencies,
    :name,
    :platform,
    :required_rubygems_version,
    :specification_version,
    :version,
    :has_rdoc,
    :default_executable,
    :metadata
  ]

  @@attributes.each do |attr_name|
    next if handled.include? attr_name
    current_value = self.send(attr_name)
    if current_value != default_value(attr_name) or
       self.class.required_attribute? attr_name then
      result << "  s.#{attr_name} = #{ruby_code current_value}"
    end
  end

  unless dependencies.empty? then
    result << nil
    result << "  if s.respond_to? :specification_version then"
    result << "    s.specification_version = #{specification_version}"
    result << nil

    result << "    if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then"

    dependencies.each do |dep|
      req = dep.requirements_list.inspect
      dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK
      result << "      s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{req})"
    end

    result << "    else"

    dependencies.each do |dep|
      version_reqs_param = dep.requirements_list.inspect
      result << "      s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
    end

    result << '    end'

    result << "  else"
    dependencies.each do |dep|
      version_reqs_param = dep.requirements_list.inspect
      result << "    s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
    end
    result << "  end"
  end

  result << "end"
  result << nil

  result.join "\n"
end
to_ruby_for_cache() click to toggle source

Returns a Ruby lighter-weight code representation of this specification, used for indexing only.

See to_ruby.

# File lib/rubygems/specification.rb, line 2272
def to_ruby_for_cache
  for_cache.to_ruby
end
traverse(trail = [], &block) click to toggle source

Recursively walk dependencies of this spec, executing the block for each hop.

# File lib/rubygems/specification.rb, line 2312
def traverse trail = [], &block
  trail = trail + [self]
  runtime_dependencies.each do |dep|
    dep.to_specs.each do |dep_spec|
      block[self, dep, dep_spec, trail + [dep_spec]]
      dep_spec.traverse(trail, &block) unless
        trail.map(&:name).include? dep_spec.name
    end
  end
end
validate(packaging = true) click to toggle source

Checks that the specification contains all required fields, and does a very basic sanity check.

Raises InvalidSpecificationException if the spec does not pass the checks..

# File lib/rubygems/specification.rb, line 2330
def validate packaging = true
  require 'rubygems/user_interaction'
  extend Gem::UserInteraction
  normalize

  nil_attributes = self.class.non_nil_attributes.find_all do |name|
    instance_variable_get("@#{name}").nil?
  end

  unless nil_attributes.empty? then
    raise Gem::InvalidSpecificationException,
      "#{nil_attributes.join ', '} must not be nil"
  end

  if packaging and rubygems_version != Gem::VERSION then
    raise Gem::InvalidSpecificationException,
          "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
  end

  @@required_attributes.each do |symbol|
    unless self.send symbol then
      raise Gem::InvalidSpecificationException,
            "missing value for attribute #{symbol}"
    end
  end

  unless String === name then
    raise Gem::InvalidSpecificationException,
          "invalid value for attribute name: \"#{name.inspect}\""
  end

  if require_paths.empty? then
    raise Gem::InvalidSpecificationException,
          'specification must have at least one require_path'
  end

  @files.delete_if            { |x| File.directory?(x) }
  @test_files.delete_if       { |x| File.directory?(x) }
  @executables.delete_if      { |x| File.directory?(File.join(@bindir, x)) }
  @extra_rdoc_files.delete_if { |x| File.directory?(x) }
  @extensions.delete_if       { |x| File.directory?(x) }

  non_files = files.reject { |x| File.file?(x) }

  unless not packaging or non_files.empty? then
    raise Gem::InvalidSpecificationException,
          "[\"#{non_files.join "\", \""}\"] are not files"
  end

  unless specification_version.is_a?(Fixnum)
    raise Gem::InvalidSpecificationException,
          'specification_version must be a Fixnum (did you mean version?)'
  end

  case platform
  when Gem::Platform, Gem::Platform::RUBY then # ok
  else
    raise Gem::InvalidSpecificationException,
          "invalid platform #{platform.inspect}, see Gem::Platform"
  end

  self.class.array_attributes.each do |field|
    val = self.send field
    klass = case field
            when :dependencies
              Gem::Dependency
            else
              String
            end

    unless Array === val and val.all? { |x| x.kind_of?(klass) } then
      raise(Gem::InvalidSpecificationException,
            "#{field} must be an Array of #{klass}")
    end
  end

  # FIX: uhhhh single element array.each?
  [:authors].each do |field|
    val = self.send field
    raise Gem::InvalidSpecificationException, "#{field} may not be empty" if
      val.empty?
  end

  unless Hash === metadata
    raise Gem::InvalidSpecificationException,
            'metadata must be a hash'
  end

  metadata.keys.each do |k|
    if !k.kind_of?(String)
      raise Gem::InvalidSpecificationException,
              'metadata keys must be a String'
    end

    if k.size > 128
      raise Gem::InvalidSpecificationException,
              "metadata key too large (#{k.size} > 128)"
    end
  end

  metadata.values.each do |k|
    if !k.kind_of?(String)
      raise Gem::InvalidSpecificationException,
              'metadata values must be a String'
    end

    if k.size > 1024
      raise Gem::InvalidSpecificationException,
              "metadata value too large (#{k.size} > 1024)"
    end
  end

  licenses.each { |license|
    if license.length > 64
      raise Gem::InvalidSpecificationException,
        "each license must be 64 characters or less"
    end
  }

  alert_warning 'licenses is empty' if licenses.empty?

  validate_permissions

  # reject lazy developers:

  # FIX: Doesn't this just evaluate to "FIXME" or "TODO"?
  lazy = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '')

  unless authors.grep(/FI XME|TO DO/).empty? then
    raise Gem::InvalidSpecificationException, "#{lazy} is not an author"
  end

  unless Array(email).grep(/FI XME|TO DO/).empty? then
    raise Gem::InvalidSpecificationException, "#{lazy} is not an email"
  end

  if description =~ /FI XME|TO DO/ then
    raise Gem::InvalidSpecificationException, "#{lazy} is not a description"
  end

  if summary =~ /FI XME|TO DO/ then
    raise Gem::InvalidSpecificationException, "#{lazy} is not a summary"
  end

  if homepage and not homepage.empty? and
     homepage !~ /\A[a-z][a-z\d+.-]*:/ then
    raise Gem::InvalidSpecificationException,
          "\"#{homepage}\" is not a URI"
  end

  # Warnings

  %w[author description email homepage summary].each do |attribute|
    value = self.send attribute
    alert_warning "no #{attribute} specified" if value.nil? or value.empty?
  end

  if description == summary then
    alert_warning 'description and summary are identical'
  end

  # TODO: raise at some given date
  alert_warning "deprecated autorequire specified" if autorequire

  executables.each do |executable|
    executable_path = File.join(bindir, executable)
    shebang = File.read(executable_path, 2) == '#!'

    alert_warning "#{executable_path} is missing #! line" unless shebang
  end

  dependencies.each do |dep|
    prerelease_dep = dep.requirements_list.any? do |req|
      Gem::Requirement.new(req).prerelease?
    end

    alert_warning "prerelease dependency on #{dep} is not recommended" if
      prerelease_dep
  end

  true
end
validate_permissions() click to toggle source

Checks to see if the files to be packaged are world-readable.

# File lib/rubygems/specification.rb, line 2516
def validate_permissions
  return if Gem.win_platform?

  files.each do |file|
    next if File.stat(file).mode & 0444 == 0444
    alert_warning "#{file} is not world-readable"
  end

  executables.each do |name|
    exec = File.join @bindir, name
    next if File.stat(exec).executable?
    alert_warning "#{exec} is not executable"
  end
end
version=(version) click to toggle source

Set the version to version, potentially also setting #required_rubygems_version if version indicates it is a prerelease.

# File lib/rubygems/specification.rb, line 2536
def version= version
  @version = Gem::Version.create(version)
  self.required_rubygems_version = '> 1.3.1' if @version.prerelease?
  invalidate_memoized_attributes

  return @version
end


class Gem::StreamUI - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::StreamUI

Gem::StreamUI implements a simple stream based user interface.

In Files

  • lib/rubygems/user_interaction.rb

Parent

Object

Attributes

errs[R]
ins[R]
outs[R]

Public Class Methods

new(in_stream, out_stream, err_stream=STDERR, usetty=true) click to toggle source
# File lib/rubygems/user_interaction.rb, line 131
def initialize(in_stream, out_stream, err_stream=STDERR, usetty=true)
  @ins = in_stream
  @outs = out_stream
  @errs = err_stream
  @usetty = usetty
end

Public Instance Methods

alert(statement, question=nil) click to toggle source

Display an informational alert. Will ask question if it is not nil.

# File lib/rubygems/user_interaction.rb, line 307
def alert(statement, question=nil)
  @outs.puts "INFO:  #{statement}"
  ask(question) if question
end
alert_error(statement, question=nil) click to toggle source

Display an error message in a location expected to get error messages. Will ask question if it is not nil.

# File lib/rubygems/user_interaction.rb, line 325
def alert_error(statement, question=nil)
  @errs.puts "ERROR:  #{statement}"
  ask(question) if question
end
alert_warning(statement, question=nil) click to toggle source

Display a warning in a location expected to get error messages. Will ask question if it is not nil.

# File lib/rubygems/user_interaction.rb, line 316
def alert_warning(statement, question=nil)
  @errs.puts "WARNING:  #{statement}"
  ask(question) if question
end
ask(question) click to toggle source

Ask a question. Returns an answer if connected to a tty, nil otherwise.

# File lib/rubygems/user_interaction.rb, line 220
def ask(question)
  return nil if not tty?

  @outs.print(question + "  ")
  @outs.flush

  result = @ins.gets
  result.chomp! if result
  result
end
ask_for_password(question) click to toggle source

Ask for a password. Does not echo response to terminal.

# File lib/rubygems/user_interaction.rb, line 235
def ask_for_password(question)
  return nil if not tty?

  require 'io/console'

  @outs.print(question + "  ")
  @outs.flush

  password = @ins.noecho {@ins.gets}
  password.chomp! if password
  password
end
ask_for_password_on_unix() click to toggle source

Asks for a password that works on unix

# File lib/rubygems/user_interaction.rb, line 286
def ask_for_password_on_unix
  return nil if not tty?

  system "stty -echo"
  password = @ins.gets
  password.chomp! if password
  system "stty echo"
  password
end
ask_for_password_on_windows() click to toggle source

Asks for a password that works on windows. Ripped from the Heroku gem.

# File lib/rubygems/user_interaction.rb, line 263
def ask_for_password_on_windows
  return nil if not tty?

  require "Win32API"
  char = nil
  password = ''

  while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do
    break if char == 10 || char == 13 # received carriage return or newline
    if char == 127 || char == 8 # backspace and delete
      password.slice!(-1, 1)
    else
      password << char.chr
    end
  end

  puts
  password
end
ask_yes_no(question, default=nil) click to toggle source

Ask a question. Returns a true for yes, false for no. If not connected to a tty, raises an exception if default is nil, otherwise returns default.

# File lib/rubygems/user_interaction.rb, line 184
def ask_yes_no(question, default=nil)
  unless tty? then
    if default.nil? then
      raise Gem::OperationNotSupportedError,
            "Not connected to a tty and no default specified"
    else
      return default
    end
  end

  default_answer = case default
                   when nil
                     'yn'
                   when true
                     'Yn'
                   else
                     'yN'
                   end

  result = nil

  while result.nil? do
    result = case ask "#{question} [#{default_answer}]"
             when /^y/ then true
             when /^n/ then false
             when /^$/  then default
             else            nil
             end
  end

  return result
end
backtrace(exception) click to toggle source

Prints a formatted backtrace to the errors stream if backtraces are enabled.

# File lib/rubygems/user_interaction.rb, line 150
def backtrace exception
  return unless Gem.configuration.backtrace

  @errs.puts "\t#{exception.backtrace.join "\n\t"}"
end
choose_from_list(question, list) click to toggle source

Choose from a list of options. question is a prompt displayed above the list. list is a list of option strings. Returns the pair [option_name, option_index].

# File lib/rubygems/user_interaction.rb, line 161
def choose_from_list(question, list)
  @outs.puts question

  list.each_with_index do |item, index|
    @outs.puts " #{index+1}. #{item}"
  end

  @outs.print "> "
  @outs.flush

  result = @ins.gets

  return nil, nil unless result

  result = result.strip.to_i - 1
  return list[result], result
end
debug(statement) click to toggle source

Display a debug message on the same location as error messages.

# File lib/rubygems/user_interaction.rb, line 333
def debug(statement)
  @errs.puts statement
end
download_reporter(*args) click to toggle source

Return a download reporter object chosen from the current verbosity

# File lib/rubygems/user_interaction.rb, line 454
def download_reporter(*args)
  if self.kind_of?(Gem::SilentUI)
    return SilentDownloadReporter.new(@outs, *args)
  end

  case Gem.configuration.verbose
  when nil, false
    SilentDownloadReporter.new(@outs, *args)
  else
    VerboseDownloadReporter.new(@outs, *args)
  end
end
progress_reporter(*args) click to toggle source

Return a progress reporter object chosen from the current verbosity.

# File lib/rubygems/user_interaction.rb, line 348
def progress_reporter(*args)
  if self.kind_of?(Gem::SilentUI)
    return SilentProgressReporter.new(@outs, *args)
  end

  case Gem.configuration.verbose
  when nil, false
    SilentProgressReporter.new(@outs, *args)
  when true
    SimpleProgressReporter.new(@outs, *args)
  else
    VerboseProgressReporter.new(@outs, *args)
  end
end
say(statement="") click to toggle source

Display a statement.

# File lib/rubygems/user_interaction.rb, line 300
def say(statement="")
  @outs.puts statement
end
terminate_interaction(status = 0) click to toggle source

Terminate the application with exit code status, running any exit handlers that might have been defined.

# File lib/rubygems/user_interaction.rb, line 341
def terminate_interaction(status = 0)
  raise Gem::SystemExitException, status
end
tty?() click to toggle source
# File lib/rubygems/user_interaction.rb, line 138
def tty?
  if RUBY_VERSION < '1.9.3' and RUBY_PLATFORM =~ /mingw|mswin/ then
    @usetty
  else
    @usetty && @ins.tty?
  end
end


class Gem::StreamUI::SilentDownloadReporter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::StreamUI::SilentDownloadReporter

An absolutely silent download reporter.

In Files

  • lib/rubygems/user_interaction.rb

Parent

Object

Public Class Methods

new(out_stream, *args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 471
def initialize(out_stream, *args)
end

Public Instance Methods

done() click to toggle source
# File lib/rubygems/user_interaction.rb, line 480
def done
end
fetch(filename, filesize) click to toggle source
# File lib/rubygems/user_interaction.rb, line 474
def fetch(filename, filesize)
end
update(current) click to toggle source
# File lib/rubygems/user_interaction.rb, line 477
def update(current)
end


class Gem::StreamUI::SilentProgressReporter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::StreamUI::SilentProgressReporter

An absolutely silent progress reporter.

In Files

  • lib/rubygems/user_interaction.rb

Parent

Object

Attributes

count[R]

Public Class Methods

new(out_stream, size, initial_message, terminal_message = nil) click to toggle source
# File lib/rubygems/user_interaction.rb, line 369
def initialize(out_stream, size, initial_message, terminal_message = nil)
end

Public Instance Methods

done() click to toggle source
# File lib/rubygems/user_interaction.rb, line 375
def done
end
updated(message) click to toggle source
# File lib/rubygems/user_interaction.rb, line 372
def updated(message)
end


class Gem::StreamUI::SimpleProgressReporter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::StreamUI::SimpleProgressReporter

A basic dotted progress reporter.

In Files

  • lib/rubygems/user_interaction.rb

Parent

Object

Included Modules

  • Gem::DefaultUserInteraction

Attributes

count[R]

Public Class Methods

new(out_stream, size, initial_message, terminal_message = "complete") click to toggle source
# File lib/rubygems/user_interaction.rb, line 388
def initialize(out_stream, size, initial_message,
               terminal_message = "complete")
  @out = out_stream
  @total = size
  @count = 0
  @terminal_message = terminal_message

  @out.puts initial_message
end

Public Instance Methods

done() click to toggle source

Prints out the terminal message.

# File lib/rubygems/user_interaction.rb, line 410
def done
  @out.puts "\n#{@terminal_message}"
end
updated(message) click to toggle source

Prints out a dot and ignores message.

# File lib/rubygems/user_interaction.rb, line 401
def updated(message)
  @count += 1
  @out.print "."
  @out.flush
end


class Gem::StreamUI::VerboseDownloadReporter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::StreamUI::VerboseDownloadReporter

A progress reporter that prints out messages about the current progress.

In Files

  • lib/rubygems/user_interaction.rb

Parent

Object

Attributes

file_name[R]
progress[R]
total_bytes[R]

Public Class Methods

new(out_stream, *args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 490
def initialize(out_stream, *args)
  @out = out_stream
  @progress = 0
end

Public Instance Methods

done() click to toggle source
# File lib/rubygems/user_interaction.rb, line 516
def done
  @progress = 100 if @units == '%'
  update_display(true, true)
end
fetch(file_name, total_bytes) click to toggle source
# File lib/rubygems/user_interaction.rb, line 495
def fetch(file_name, total_bytes)
  @file_name = file_name
  @total_bytes = total_bytes.to_i
  @units = @total_bytes.zero? ? 'B' : '%'

  update_display(false)
end
update(bytes) click to toggle source
# File lib/rubygems/user_interaction.rb, line 503
def update(bytes)
  new_progress = if @units == 'B' then
                   bytes
                 else
                   ((bytes.to_f * 100) / total_bytes.to_f).ceil
                 end

  return if new_progress == @progress

  @progress = new_progress
  update_display
end


class Gem::StreamUI::VerboseProgressReporter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::StreamUI::VerboseProgressReporter

A progress reporter that prints out messages about the current progress.

In Files

  • lib/rubygems/user_interaction.rb

Parent

Object

Included Modules

  • Gem::DefaultUserInteraction

Attributes

count[R]

Public Class Methods

new(out_stream, size, initial_message, terminal_message = 'complete') click to toggle source
# File lib/rubygems/user_interaction.rb, line 425
def initialize(out_stream, size, initial_message,
               terminal_message = 'complete')
  @out = out_stream
  @total = size
  @count = 0
  @terminal_message = terminal_message

  @out.puts initial_message
end

Public Instance Methods

done() click to toggle source

Prints out the terminal message.

# File lib/rubygems/user_interaction.rb, line 446
def done
  @out.puts @terminal_message
end
updated(message) click to toggle source

Prints out the position relative to the total and the message.

# File lib/rubygems/user_interaction.rb, line 438
def updated(message)
  @count += 1
  @out.puts "#{@count}/#{@total}: #{message}"
end


class Gem::SystemExitException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::SystemExitException

Raised to indicate that a system exit should occur with the specified #exit_code

In Files

  • lib/rubygems/exceptions.rb

Parent

SystemExit

Attributes

exit_code[RW]

Public Class Methods

new(exit_code) click to toggle source
# File lib/rubygems/exceptions.rb, line 102
def initialize(exit_code)
  @exit_code = exit_code

  super "Exiting RubyGems with exit_code #{exit_code}"
end


class Gem::TestCase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::TestCase

RubyGemTestCase provides a variety of methods for testing rubygems and gem-related behavior in a sandbox. Through RubyGemTestCase you can install and uninstall gems, fetch remote gems through a stub fetcher and be assured your normal set of gems is not affected.

Tests are always run at a safe level of 1.

In Files

  • lib/rubygems/test_case.rb
  • lib/test/unit/parallel.rb

Parent

MiniTest::Unit::TestCase

Included Modules

  • Gem::DefaultUserInteraction

Public Class Methods

cert_path(cert_name) click to toggle source

Returns the path to the certificate named cert_name from test/rubygems/.

# File lib/rubygems/test_case.rb, line 1070
def self.cert_path cert_name
  if 32 == (Time.at(2**32) rescue 32) then
    cert_file =
      File.expand_path "../../../test/rubygems/#{cert_name}_cert_32.pem",
                       __FILE__

    return cert_file if File.exist? cert_file
  end

  File.expand_path "../../../test/rubygems/#{cert_name}_cert.pem", __FILE__
end
key_path(key_name) click to toggle source

Returns the path tot he key named key_name from test/rubygems

# File lib/rubygems/test_case.rb, line 1096
def self.key_path key_name
  File.expand_path "../../../test/rubygems/#{key_name}_key.pem", __FILE__
end
load_cert(cert_name) click to toggle source

Loads certificate named cert_name from test/rubygems/.

# File lib/rubygems/test_case.rb, line 1058
def self.load_cert cert_name
  cert_file = cert_path cert_name

  cert = File.read cert_file

  OpenSSL::X509::Certificate.new cert
end
load_key(key_name) click to toggle source

Loads an RSA private key named key_name in test/rubygems/

# File lib/rubygems/test_case.rb, line 1085
def self.load_key key_name
  key_file = key_path key_name

  key = File.read key_file

  OpenSSL::PKey::RSA.new key
end
make_command() click to toggle source

Returns the make command for the current platform. For versions of Ruby built on MS Windows with VC++ or Borland it will return 'nmake'. On all other platforms, including Cygwin, it will return 'make'.

# File lib/rubygems/test_case.rb, line 911
def self.make_command
  ENV["make"] || (vc_windows? ? 'nmake' : 'make')
end
process_based_port() click to toggle source

Allows tests to use a random (but controlled) port number instead of a hardcoded one. This helps CI tools when running parallels builds on the same builder slave.

# File lib/rubygems/test_case.rb, line 944
def self.process_based_port
  @@process_based_port ||= 8000 + $$ % 1000
end
rubybin() click to toggle source

Finds the path to the ruby executable

# File lib/rubygems/test_case.rb, line 977
def self.rubybin
  ruby = ENV["RUBY"]
  return ruby if ruby
  ruby = "ruby"
  rubyexe = "#{ruby}.exe"

  3.times do
    if File.exist? ruby and File.executable? ruby and !File.directory? ruby
      return File.expand_path(ruby)
    end
    if File.exist? rubyexe and File.executable? rubyexe
      return File.expand_path(rubyexe)
    end
    ruby = File.join("..", ruby)
  end

  begin
    require "rbconfig"
    File.join(RbConfig::CONFIG["bindir"],
              RbConfig::CONFIG["ruby_install_name"] +
              RbConfig::CONFIG["EXEEXT"])
  rescue LoadError
    "ruby"
  end
end
vc_windows?() click to toggle source

Returns whether or not we're on a version of Ruby built with VC++ (or Borland) versus Cygwin, Mingw, etc.

# File lib/rubygems/test_case.rb, line 894
def self.vc_windows?
  RUBY_PLATFORM.match('mswin')
end
win_platform?() click to toggle source

Is this test being run on a Windows platform?

# File lib/rubygems/test_case.rb, line 879
def self.win_platform?
  Gem.win_platform?
end

Public Instance Methods

add_to_fetcher(spec, path=nil, repo=@gem_repo) click to toggle source

Add spec to +@fetcher+ serving the data in the file path. repo indicates which repo to make spec appear to be in.

# File lib/rubygems/test_case.rb, line 823
def add_to_fetcher(spec, path=nil, repo=@gem_repo)
  path ||= spec.cache_file
  @fetcher.data["#{@gem_repo}gems/#{spec.file_name}"] = read_binary(path)
end
all_spec_names() click to toggle source
# File lib/rubygems/test_case.rb, line 433
def all_spec_names
  Gem::Specification.map(&:full_name)
end
assert_contains_make_command(target, output, msg = nil) { |make, line| ... } click to toggle source
# File lib/rubygems/test_case.rb, line 127
def assert_contains_make_command(target, output, msg = nil)
  if output.match(/\n/)
    msg = message(msg) {
      'Expected output containing make command "%s": %s' % [
        ('%s %s' % [make_command, target]).rstrip,
        output.inspect
      ]
    }
  else
    msg = message(msg) {
      'Expected make command "%s": %s' % [
        ('%s %s' % [make_command, target]).rstrip,
        output.inspect
      ]
    }
  end

  assert scan_make_command_lines(output).any? { |line|
    make = parse_make_command_line(line)

    if make[:targets].include?(target)
      yield make, line if block_given?
      true
    else
      false
    end
  }, msg
end
assert_path_exists(path, msg = nil) click to toggle source

TODO: move to minitest

# File lib/rubygems/test_case.rb, line 88
def assert_path_exists path, msg = nil
  msg = message(msg) { "Expected path '#{path}' to exist" }
  assert File.exist?(path), msg
end
build_rake_in(good=true) { |rake| ... } click to toggle source

Allows the proper version of rake to be used for the test.

# File lib/rubygems/test_case.rb, line 958
def build_rake_in(good=true)
  gem_ruby = Gem.ruby
  Gem.ruby = @@ruby
  env_rake = ENV["rake"]
  rake = (good ? @@good_rake : @@bad_rake)
  ENV["rake"] = rake
  yield rake
ensure
  Gem.ruby = gem_ruby
  if env_rake
    ENV["rake"] = env_rake
  else
    ENV.delete("rake")
  end
end
create_tmpdir() click to toggle source

creates a temporary directory with hax TODO: deprecate and remove

# File lib/rubygems/test_case.rb, line 384
def create_tmpdir
  tmpdir = nil
  Dir.chdir Dir.tmpdir do tmpdir = Dir.pwd end # HACK OSX /private/tmp
  tmpdir = File.join tmpdir, "test_rubygems_#{$$}"
  FileUtils.mkdir_p tmpdir
  return tmpdir
end
dep(name, *requirements) click to toggle source

Construct a new Gem::Dependency.

# File lib/rubygems/test_case.rb, line 1010
def dep name, *requirements
  Gem::Dependency.new name, *requirements
end
install_default_gems(*specs) click to toggle source

Installs the provided default specs including writing the spec file

# File lib/rubygems/test_case.rb, line 549
def install_default_gems(*specs)
  install_default_specs(*specs)

  specs.each do |spec|
    open spec.loaded_from, 'w' do |io|
      io.write spec.to_ruby_for_cache
    end
  end
end
install_default_specs(*specs) click to toggle source

Install the provided default specs

# File lib/rubygems/test_case.rb, line 562
def install_default_specs(*specs)
  install_specs(*specs)
  specs.each do |spec|
    Gem.register_default_spec(spec)
  end
end
install_gem(spec, options = {}) click to toggle source

Builds and installs the Gem::Specification spec

# File lib/rubygems/test_case.rb, line 346
def install_gem spec, options = {}
  require 'rubygems/installer'

  gem = File.join @tempdir, "gems", "#{spec.full_name}.gem"

  unless File.exists? gem
    use_ui Gem::MockGemUi.new do
      Dir.chdir @tempdir do
        Gem::Package.build spec
      end
    end

    gem = File.join(@tempdir, File.basename(spec.cache_file)).untaint
  end

  Gem::Installer.new(gem, options.merge({:wrappers => true})).install
end
install_gem_user(spec) click to toggle source

Builds and installs the Gem::Specification spec into the user dir

# File lib/rubygems/test_case.rb, line 367
def install_gem_user spec
  install_gem spec, :user_install => true
end
install_specs(*specs) click to toggle source

Install the provided specs

# File lib/rubygems/test_case.rb, line 541
def install_specs(*specs)
  Gem::Specification.add_specs(*specs)
  Gem.searcher = nil
end
make_command() click to toggle source

Returns the make command for the current platform. For versions of Ruby built on MS Windows with VC++ or Borland it will return 'nmake'. On all other platforms, including Cygwin, it will return 'make'.

# File lib/rubygems/test_case.rb, line 920
def make_command
  ENV["make"] || (vc_windows? ? 'nmake' : 'make')
end
mu_pp(obj) click to toggle source

Enables pretty-print for all tests

# File lib/rubygems/test_case.rb, line 395
def mu_pp(obj)
  s = ''
  s = PP.pp obj, s
  s = s.force_encoding(Encoding.default_external) if defined? Encoding
  s.chomp
end
new_default_spec(name, version, deps = nil, *files) click to toggle source
# File lib/rubygems/test_case.rb, line 613
def new_default_spec(name, version, deps = nil, *files)
  spec = new_spec(name, version, deps)
  spec.loaded_from = File.join(@default_spec_dir, spec.spec_name)
  spec.files = files

  lib_dir = File.join(@tempdir, "default_gems", "lib")
  $LOAD_PATH.unshift(lib_dir)
  files.each do |file|
    rb_path = File.join(lib_dir, file)
    FileUtils.mkdir_p(File.dirname(rb_path))
    File.open(rb_path, "w") do |rb|
      rb << "# #{file}"
    end
  end

  spec
end
new_spec(name, version, deps = nil, *files) { |s| ... } click to toggle source

Create a new spec (or gem if passed an array of files) and set it up properly. Use this instead of #util_spec and util_gem.

# File lib/rubygems/test_case.rb, line 573
def new_spec name, version, deps = nil, *files
  require 'rubygems/specification'

  spec = Gem::Specification.new do |s|
    s.platform    = Gem::Platform::RUBY
    s.name        = name
    s.version     = version
    s.author      = 'A User'
    s.email       = 'example@example.com'
    s.homepage    = 'http://example.com'
    s.summary     = "this is a summary"
    s.description = "This is a test description"

    Array(deps).each do |n, req|
      s.add_dependency n, (req || '>= 0')
    end

    s.files.push(*files) unless files.empty?

    yield s if block_given?
  end

  spec.loaded_from = spec.spec_file

  unless files.empty? then
    write_file spec.spec_file do |io|
      io.write spec.to_ruby_for_cache
    end

    util_build_gem spec

    cache_file = File.join @tempdir, 'gems', "#{spec.full_name}.gem"
    FileUtils.mkdir_p File.dirname cache_file
    FileUtils.mv spec.cache_file, cache_file
    FileUtils.rm spec.spec_file
  end

  spec
end
nmake_found?() click to toggle source

Returns whether or not the nmake command could be found.

# File lib/rubygems/test_case.rb, line 927
def nmake_found?
  system('nmake /? 1>NUL 2>&1')
end
parse_make_command_line(line) click to toggle source
# File lib/rubygems/test_case.rb, line 103
def parse_make_command_line(line)
  command, *args = line.shellsplit

  targets = []
  macros = {}

  args.each do |arg|
    case arg
    when /\A(\w+)=/
      macros[$1] = $'
    else
      targets << arg
    end
  end

  targets << '' if targets.empty?

  {
    :command => command,
    :targets => targets,
    :macros => macros,
  }
end
process_based_port() click to toggle source

See ::process_based_port

# File lib/rubygems/test_case.rb, line 951
def process_based_port
  self.class.process_based_port
end
quick_gem(name, version='2') { |s| ... } click to toggle source

Creates a Gem::Specification with a minimum of extra work. name and version are the gem's name and version, platform, author, email, homepage, summary and description are defaulted. The specification is yielded for customization.

The gem is added to the installed gems in +@gemhome+ and the runtime.

Use this with write_file to build an installed gem.

# File lib/rubygems/test_case.rb, line 447
def quick_gem(name, version='2')
  require 'rubygems/specification'

  spec = Gem::Specification.new do |s|
    s.platform    = Gem::Platform::RUBY
    s.name        = name
    s.version     = version
    s.author      = 'A User'
    s.email       = 'example@example.com'
    s.homepage    = 'http://example.com'
    s.summary     = "this is a summary"
    s.description = "This is a test description"

    yield(s) if block_given?
  end

  Gem::Specification.map # HACK: force specs to (re-)load before we write

  written_path = write_file spec.spec_file do |io|
    io.write spec.to_ruby_for_cache
  end

  spec.loaded_from = spec.loaded_from = written_path

  Gem::Specification.add_spec spec.for_cache

  return spec
end
quick_spec(name, version = '2') { |s| ... } click to toggle source
# File lib/rubygems/test_case.rb, line 476
def quick_spec name, version = '2'
  # TODO: deprecate
  require 'rubygems/specification'

  spec = Gem::Specification.new do |s|
    s.platform    = Gem::Platform::RUBY
    s.name        = name
    s.version     = version
    s.author      = 'A User'
    s.email       = 'example@example.com'
    s.homepage    = 'http://example.com'
    s.summary     = "this is a summary"
    s.description = "This is a test description"

    yield(s) if block_given?
  end

  spec.loaded_from = spec.spec_file

  Gem::Specification.add_spec spec

  return spec
end
read_binary(path) click to toggle source

Reads a binary file at path

# File lib/rubygems/test_case.rb, line 414
def read_binary(path)
  Gem.read_binary path
end
read_cache(path) click to toggle source

Reads a Marshal file at path

# File lib/rubygems/test_case.rb, line 405
def read_cache(path)
  open path.dup.untaint, 'rb' do |io|
    Marshal.load io.read
  end
end
refute_path_exists(path, msg = nil) click to toggle source

TODO: move to minitest

# File lib/rubygems/test_case.rb, line 94
def refute_path_exists path, msg = nil
  msg = message(msg) { "Expected path '#{path}' to not exist" }
  refute File.exist?(path), msg
end
req(*requirements) click to toggle source

Constructs a new Gem::Requirement.

# File lib/rubygems/test_case.rb, line 1017
def req *requirements
  return requirements.first if Gem::Requirement === requirements.first
  Gem::Requirement.create requirements
end
scan_make_command_lines(output) click to toggle source
# File lib/rubygems/test_case.rb, line 99
def scan_make_command_lines(output)
  output.scan(/^#{Regexp.escape make_command}(?:[[:blank:]].*)?$/)
end
setup() click to toggle source

setup prepares a sandboxed location to install gems. All installs are directed to a temporary directory. All install plugins are removed.

If the RUBY environment variable is set the given path is used for Gem.ruby. The local platform is set to i386-mswin32 for Windows or i686-darwin8.10.1 otherwise.

If the KEEP_FILES environment variable is set the files will not be removed from /tmp/test_rubygems_#{$$}.#{Time.now.to_i}.

# File lib/rubygems/test_case.rb, line 176
def setup
  super

  @orig_gem_home = ENV['GEM_HOME']
  @orig_gem_path = ENV['GEM_PATH']

  @current_dir = Dir.pwd
  @ui = Gem::MockGemUi.new

  tmpdir = File.expand_path Dir.tmpdir
  tmpdir.untaint

  if ENV['KEEP_FILES'] then
    @tempdir = File.join(tmpdir, "test_rubygems_#{$$}.#{Time.now.to_i}")
  else
    @tempdir = File.join(tmpdir, "test_rubygems_#{$$}")
  end
  @tempdir.untaint

  FileUtils.mkdir_p @tempdir

  # This makes the tempdir consistent on OS X.
  # File.expand_path Dir.tmpdir                      #=> "/var/..."
  # Dir.chdir Dir.tmpdir do File.expand_path '.' end #=> "/private/var/..."
  # TODO use File#realpath above instead of #expand_path once 1.8 support is
  # dropped.
  Dir.chdir @tempdir do
    @tempdir = File.expand_path '.'
    @tempdir.untaint
  end

  @gemhome  = File.join @tempdir, 'gemhome'
  @userhome = File.join @tempdir, 'userhome'

  @orig_ruby = if ENV['RUBY'] then
                 ruby = Gem.instance_variable_get :@ruby
                 Gem.instance_variable_set :@ruby, ENV['RUBY']
                 ruby
               end

  Gem.ensure_gem_subdirectories @gemhome

  @orig_LOAD_PATH = $LOAD_PATH.dup
  $LOAD_PATH.map! { |s| File.expand_path(s).untaint }

  Dir.chdir @tempdir

  @orig_ENV_HOME = ENV['HOME']
  ENV['HOME'] = @userhome
  Gem.instance_variable_set :@user_home, nil

  FileUtils.mkdir_p @gemhome
  FileUtils.mkdir_p @userhome

  @default_dir = File.join @tempdir, 'default'
  @default_spec_dir = File.join @default_dir, "specifications", "default"
  Gem.instance_variable_set :@default_dir, @default_dir
  FileUtils.mkdir_p @default_spec_dir

  # We use Gem::Specification.reset the first time only so that if there
  # are unresolved deps that leak into the whole test suite, they're at least
  # reported once.
  if @@initial_reset
    Gem::Specification.unresolved_deps.clear # done to avoid cross-test warnings
  else
    @@initial_reset = true
    Gem::Specification.reset
  end
  Gem.use_paths(@gemhome)

  Gem::Security.reset

  Gem.loaded_specs.clear
  Gem.clear_default_specs
  Gem::Specification.unresolved_deps.clear

  Gem.configuration.verbose = true
  Gem.configuration.update_sources = true

  Gem::RemoteFetcher.fetcher = Gem::FakeFetcher.new

  @gem_repo = "http://gems.example.com/"
  @uri = URI.parse @gem_repo
  Gem.sources.replace [@gem_repo]

  Gem.searcher = nil
  Gem::SpecFetcher.fetcher = nil
  @orig_BASERUBY = Gem::ConfigMap[:BASERUBY]
  Gem::ConfigMap[:BASERUBY] = Gem::ConfigMap[:ruby_install_name]

  @orig_arch = Gem::ConfigMap[:arch]

  if win_platform?
    util_set_arch 'i386-mswin32'
  else
    util_set_arch 'i686-darwin8.10.1'
  end

  @marshal_version = "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"

  # TODO: move to installer test cases
  Gem.post_build_hooks.clear
  Gem.post_install_hooks.clear
  Gem.done_installing_hooks.clear
  Gem.post_reset_hooks.clear
  Gem.post_uninstall_hooks.clear
  Gem.pre_install_hooks.clear
  Gem.pre_reset_hooks.clear
  Gem.pre_uninstall_hooks.clear

  # TODO: move to installer test cases
  Gem.post_build do |installer|
    @post_build_hook_arg = installer
    true
  end

  Gem.post_install do |installer|
    @post_install_hook_arg = installer
  end

  Gem.post_uninstall do |uninstaller|
    @post_uninstall_hook_arg = uninstaller
  end

  Gem.pre_install do |installer|
    @pre_install_hook_arg = installer
    true
  end

  Gem.pre_uninstall do |uninstaller|
    @pre_uninstall_hook_arg = uninstaller
  end
end
spec(name, version, &block) click to toggle source

Constructs a new Gem::Specification.

# File lib/rubygems/test_case.rb, line 1025
def spec name, version, &block
  Gem::Specification.new name, v(version), &block
end
teardown() click to toggle source

teardown restores the process to its original state and removes the tempdir unless the KEEP_FILES environment variable was set.

# File lib/rubygems/test_case.rb, line 314
def teardown
  $LOAD_PATH.replace @orig_LOAD_PATH if @orig_LOAD_PATH

  Gem::ConfigMap[:BASERUBY] = @orig_BASERUBY
  Gem::ConfigMap[:arch] = @orig_arch

  if defined? Gem::RemoteFetcher then
    Gem::RemoteFetcher.fetcher = nil
  end

  Dir.chdir @current_dir

  FileUtils.rm_rf @tempdir unless ENV['KEEP_FILES']

  ENV['GEM_HOME'] = @orig_gem_home
  ENV['GEM_PATH'] = @orig_gem_path

  _ = @orig_ruby
  Gem.instance_variable_set :@ruby, @orig_ruby if @orig_ruby

  if @orig_ENV_HOME then
    ENV['HOME'] = @orig_ENV_HOME
  else
    ENV.delete 'HOME'
  end

  Gem.instance_variable_set :@default_dir, nil
end
uninstall_gem(spec) click to toggle source

Uninstalls the Gem::Specification spec

# File lib/rubygems/test_case.rb, line 373
def uninstall_gem spec
  require 'rubygems/uninstaller'

  Gem::Uninstaller.new(spec.name,
                       :executables => true, :user_install => true).uninstall
end
util_build_gem(spec) click to toggle source

Builds a gem from spec and places it in File.join @gemhome, 'cache'. Automatically creates files based on spec.files

# File lib/rubygems/test_case.rb, line 504
def util_build_gem(spec)
  dir = spec.gem_dir
  FileUtils.mkdir_p dir

  Dir.chdir dir do
    spec.files.each do |file|
      next if File.exist? file
      FileUtils.mkdir_p File.dirname(file)
      File.open file, 'w' do |fp| fp.puts "# #{file}" end
    end

    use_ui Gem::MockGemUi.new do
      Gem::Package.build spec
    end

    cache = spec.cache_file
    FileUtils.mv File.basename(cache), cache
  end
end
util_clear_gems() click to toggle source

Removes all installed gems from +@gemhome+.

# File lib/rubygems/test_case.rb, line 532
def util_clear_gems
  FileUtils.rm_rf File.join(@gemhome, "gems") # TODO: use Gem::Dirs
  FileUtils.rm_rf File.join(@gemhome, "specifications")
  Gem::Specification.reset
end
util_gem(name, version, deps = nil, &block) click to toggle source

Creates a gem with name, version and deps. The specification will be yielded before gem creation for customization. The gem will be placed in File.join @tempdir, 'gems'. The specification and .gem file location are returned.

# File lib/rubygems/test_case.rb, line 658
def util_gem(name, version, deps = nil, &block)
  # TODO: deprecate
  raise "deps or block, not both" if deps and block

  if deps then
    block = proc do |s|
      # Since Hash#each is unordered in 1.8, sort
      # the keys and iterate that way so the tests are
      # deterministic on all implementations.
      deps.keys.sort.each do |n|
        s.add_dependency n, (deps[n] || '>= 0')
      end
    end
  end

  spec = quick_gem(name, version, &block)

  util_build_gem spec

  cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem"
  FileUtils.mkdir_p File.dirname cache_file
  FileUtils.mv spec.cache_file, cache_file
  FileUtils.rm spec.spec_file

  spec.loaded_from = nil

  [spec, cache_file]
end
util_gzip(data) click to toggle source

Gzips data.

# File lib/rubygems/test_case.rb, line 690
def util_gzip(data)
  out = StringIO.new

  Zlib::GzipWriter.wrap out do |io|
    io.write data
  end

  out.string
end
util_make_gems(prerelease = false) click to toggle source

Creates several default gems which all have a lib/code.rb file. The gems are not installed but are available in the cache dir.

+@a1+

gem a version 1, this is the best-described gem.

+@a2+

gem a version 2

+@a3a

gem a version 3.a

+@a_evil9+

gem a_evil version 9, use this to ensure similarly-named gems don't collide with a.

+@b2+

gem b version 2

+@c1_2+

gem c version 1.2

+@pl1+

gem pl version 1, this gem has a legacy platform of i386-linux.

Additional prerelease gems may also be created:

+@a2_pre+

gem a version 2.a

TODO: nuke this and fix tests. this should speed up a lot

# File lib/rubygems/test_case.rb, line 718
  def util_make_gems(prerelease = false)
    @a1 = quick_gem 'a', '1' do |s|
      s.files = %w[lib/code.rb]
      s.require_paths = %w[lib]
      s.date = Gem::Specification::TODAY - 86400
      s.homepage = 'http://a.example.com'
      s.email = %w[example@example.com example2@example.com]
      s.authors = %w[Example Example2]
      s.description = <<-DESC
This line is really, really long.  So long, in fact, that it is more than eighty characters long!  The purpose of this line is for testing wrapping behavior because sometimes people don't wrap their text to eighty characters.  Without the wrapping, the text might not look good in the RSS feed.

Also, a list:
  * An entry that\'s actually kind of sort
  * an entry that\'s really long, which will probably get wrapped funny.  That's ok, somebody wasn't thinking straight when they made it more than eighty characters.
      DESC
    end

    init = proc do |s|
      s.files = %w[lib/code.rb]
      s.require_paths = %w[lib]
    end

    @a2      = quick_gem('a', '2',      &init)
    @a3a     = quick_gem('a', '3.a',    &init)
    @a_evil9 = quick_gem('a_evil', '9', &init)
    @b2      = quick_gem('b', '2',      &init)
    @c1_2    = quick_gem('c', '1.2',    &init)
    @x       = quick_gem('x', '1', &init)
    @dep_x   = quick_gem('dep_x', '1') do |s|
      s.files = %w[lib/code.rb]
      s.require_paths = %w[lib]
      s.add_dependency 'x', '>= 1'
    end

    @pl1     = quick_gem 'pl', '1' do |s| # l for legacy
      s.files = %w[lib/code.rb]
      s.require_paths = %w[lib]
      s.platform = Gem::Platform.new 'i386-linux'
      s.instance_variable_set :@original_platform, 'i386-linux'
    end

    if prerelease
      @a2_pre = quick_gem('a', '2.a', &init)
      write_file File.join(*%W[gems #{@a2_pre.original_name} lib code.rb])
      util_build_gem @a2_pre
    end

    write_file File.join(*%W[gems #{@a1.original_name}   lib code.rb])
    write_file File.join(*%W[gems #{@a2.original_name}   lib code.rb])
    write_file File.join(*%W[gems #{@a3a.original_name}  lib code.rb])
    write_file File.join(*%W[gems #{@b2.original_name}   lib code.rb])
    write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb])
    write_file File.join(*%W[gems #{@pl1.original_name}  lib code.rb])
    write_file File.join(*%W[gems #{@x.original_name}  lib code.rb])
    write_file File.join(*%W[gems #{@dep_x.original_name}  lib code.rb])

    [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2, @pl1, @x, @dep_x].each do |spec|
      util_build_gem spec
    end

    FileUtils.rm_r File.join(@gemhome, "gems", @pl1.original_name)
  end
util_remove_gem(spec) click to toggle source
# File lib/rubygems/test_case.rb, line 524
def util_remove_gem(spec)
  FileUtils.rm_rf spec.cache_file
  FileUtils.rm_rf spec.spec_file
end
util_set_arch(arch) click to toggle source

Set the platform to arch

# File lib/rubygems/test_case.rb, line 784
def util_set_arch(arch)
  Gem::ConfigMap[:arch] = arch
  platform = Gem::Platform.new arch

  Gem.instance_variable_set :@platforms, nil
  Gem::Platform.instance_variable_set :@local, nil

  platform
end
util_setup_fake_fetcher(prerelease = false) click to toggle source

Sets up a fake fetcher using the gems from util_make_gems. Optionally additional prerelease gems may be included.

Gems created by this method may be fetched using Gem::RemoteFetcher.

# File lib/rubygems/test_case.rb, line 800
def util_setup_fake_fetcher(prerelease = false)
  require 'zlib'
  require 'socket'
  require 'rubygems/remote_fetcher'

  @fetcher = Gem::FakeFetcher.new

  util_make_gems(prerelease)
  Gem::Specification.reset

  @all_gems = [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2].sort
  @all_gem_names = @all_gems.map { |gem| gem.full_name }

  gem_names = [@a1.full_name, @a2.full_name, @a3a.full_name, @b2.full_name]
  @gem_names = gem_names.sort.join("\n")

  Gem::RemoteFetcher.fetcher = @fetcher
end
util_setup_spec_fetcher(*specs) click to toggle source

Sets up Gem::SpecFetcher to return information from the gems in specs. Best used with +@all_gems+ from util_setup_fake_fetcher.

# File lib/rubygems/test_case.rb, line 832
def util_setup_spec_fetcher(*specs)
  specs -= Gem::Specification._all
  Gem::Specification.add_specs(*specs)

  spec_fetcher = Gem::SpecFetcher.fetcher

  prerelease, all = Gem::Specification.partition { |spec|
    spec.version.prerelease?
  }

  spec_fetcher.specs[@uri] = []
  all.each do |spec|
    spec_fetcher.specs[@uri] << spec.name_tuple
  end

  spec_fetcher.latest_specs[@uri] = []
  Gem::Specification.latest_specs.each do |spec|
    spec_fetcher.latest_specs[@uri] << spec.name_tuple
  end

  spec_fetcher.prerelease_specs[@uri] = []
  prerelease.each do |spec|
    spec_fetcher.prerelease_specs[@uri] << spec.name_tuple
  end

  v = Gem.marshal_version

  Gem::Specification.each do |spec|
    path = "#{@gem_repo}quick/Marshal.#{v}/#{spec.original_name}.gemspec.rz"
    data = Marshal.dump spec
    data_deflate = Zlib::Deflate.deflate data
    @fetcher.data[path] = data_deflate
  end unless Gem::RemoteFetcher === @fetcher # HACK for test_download_to_cache

  nil # force errors
end
util_spec(name, version, deps = nil, &block) click to toggle source

Creates a spec with name, version and deps.

# File lib/rubygems/test_case.rb, line 634
def util_spec(name, version, deps = nil, &block)
  # TODO: deprecate
  raise "deps or block, not both" if deps and block

  if deps then
    block = proc do |s|
      # Since Hash#each is unordered in 1.8, sort
      # the keys and iterate that way so the tests are
      # deteriminstic on all implementations.
      deps.keys.sort.each do |n|
        s.add_dependency n, (deps[n] || '>= 0')
      end
    end
  end

  quick_spec(name, version, &block)
end
util_zip(data) click to toggle source

Deflates data

# File lib/rubygems/test_case.rb, line 872
def util_zip(data)
  Zlib::Deflate.deflate data
end
v(string) click to toggle source

Construct a new Gem::Version.

# File lib/rubygems/test_case.rb, line 1032
def v string
  Gem::Version.create string
end
vc_windows?() click to toggle source

Returns whether or not we're on a version of Ruby built with VC++ (or Borland) versus Cygwin, Mingw, etc.

# File lib/rubygems/test_case.rb, line 902
def vc_windows?
  RUBY_PLATFORM.match('mswin')
end
wait_for_child_process_to_exit() click to toggle source

In case we're building docs in a background process, this method waits for that process to exit (or if it's already been reaped, or never happened, swallows the Errno::ECHILD error).

# File lib/rubygems/test_case.rb, line 934
def wait_for_child_process_to_exit
  Process.wait if Process.respond_to?(:fork)
rescue Errno::ECHILD
end
win_platform?() click to toggle source

Is this test being run on a Windows platform?

# File lib/rubygems/test_case.rb, line 886
def win_platform?
  Gem.win_platform?
end
write_file(path) { |io| ... } click to toggle source

Writes a binary file to path which is relative to +@gemhome+

# File lib/rubygems/test_case.rb, line 421
def write_file(path)
  path = File.join @gemhome, path unless Pathname.new(path).absolute?
  dir = File.dirname path
  FileUtils.mkdir_p dir

  open path, 'wb' do |io|
    yield io if block_given?
  end

  path
end


class Gem::TestCase::StaticSet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::TestCase::StaticSet

In Files

  • lib/rubygems/test_case.rb

Parent

Object

Public Class Methods

new(specs) click to toggle source
# File lib/rubygems/test_case.rb, line 1037
def initialize(specs)
  @specs = specs.sort_by { |s| s.full_name }
end

Public Instance Methods

find_all(dep) click to toggle source
# File lib/rubygems/test_case.rb, line 1047
def find_all(dep)
  @specs.find_all { |s| dep.matches_spec? s }
end
find_spec(dep) click to toggle source
# File lib/rubygems/test_case.rb, line 1041
def find_spec(dep)
  @specs.reverse_each do |s|
    return s if dep.matches_spec? s
  end
end
prefetch(reqs) click to toggle source
# File lib/rubygems/test_case.rb, line 1051
def prefetch(reqs)
end


module Gem::Text - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::Text

A collection of text-wrangling methods

In Files

  • lib/rubygems/text.rb

Public Instance Methods

format_text(text, wrap, indent=0) click to toggle source

Wraps text to wrap characters and optionally indents by indent characters

# File lib/rubygems/text.rb, line 12
def format_text(text, wrap, indent=0)
  result = []
  work = text.dup

  while work.length > wrap do
    if work =~ /^(.{0,#{wrap}})[ \n]/ then
      result << $1.rstrip
      work.slice!(0, $&.length)
    else
      result << work.slice!(0, wrap)
    end
  end

  result << work if work.length.nonzero?
  result.join("\n").gsub(/^/, " " * indent)
end
levenshtein_distance(str1, str2) click to toggle source

This code is based directly on the Text gem implementation Returns a value representing the “cost” of transforming str1 into str2

# File lib/rubygems/text.rb, line 31
def levenshtein_distance str1, str2
  s = str1
  t = str2
  n = s.length
  m = t.length
  max = n/2

  return m if (0 == n)
  return n if (0 == m)
  return n if (n - m).abs > max

  d = (0..m).to_a
  x = nil

  n.times do |i|
    e = i+1

    m.times do |j|
      cost = (s[i] == t[j]) ? 0 : 1
      x = [
           d[j+1] + 1, # insertion
           e + 1,      # deletion
           d[j] + cost # substitution
          ].min
      d[j] = e
      e = x
    end

    d[m] = x
  end

  return x
end


class Gem::Uninstaller - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Uninstaller

An Uninstaller.

The uninstaller fires pre and post uninstall hooks. Hooks can be added either through a rubygems_plugin.rb file in an installed gem or via a rubygems/defaults/#{RUBY_ENGINE}.rb or rubygems/defaults/operating_system.rb file. See Gem.pre_uninstall and Gem.post_uninstall for details.

In Files

  • lib/rubygems/uninstaller.rb

Parent

Object

Included Modules

  • Gem::UserInteraction

Attributes

bin_dir[R]

The directory a gem's executables will be installed into

gem_home[R]

The gem repository the gem will be installed into

spec[R]

The Gem::Specification for the gem being uninstalled, only set during uninstall_gem

Public Class Methods

new(gem, options = {}) click to toggle source

Constructs an uninstaller that will uninstall gem

# File lib/rubygems/uninstaller.rb, line 44
def initialize(gem, options = {})
  # TODO document the valid options
  @gem               = gem
  @version           = options[:version] || Gem::Requirement.default
  @gem_home          = File.expand_path(options[:install_dir] || Gem.dir)
  @force_executables = options[:executables]
  @force_all         = options[:all]
  @force_ignore      = options[:ignore]
  @bin_dir           = options[:bin_dir]
  @format_executable = options[:format_executable]

  # Indicate if development dependencies should be checked when
  # uninstalling. (default: false)
  #
  @check_dev         = options[:check_dev]

  if options[:force]
    @force_all = true
    @force_ignore = true
  end

  # only add user directory if install_dir is not set
  @user_install = false
  @user_install = options[:user_install] unless options[:install_dir]
end

Public Instance Methods

ask_if_ok(spec) click to toggle source
# File lib/rubygems/uninstaller.rb, line 293
def ask_if_ok(spec)
  msg = ['']
  msg << 'You have requested to uninstall the gem:'
  msg << "\t#{spec.full_name}"
  msg << ''

  siblings = Gem::Specification.select do |s|
               s.name == spec.name && s.full_name != spec.full_name
             end

  spec.dependent_gems.each do |dep_spec, dep, satlist|
    unless siblings.any? { |s| s.satisfies_requirement? dep }
      msg << "#{dep_spec.name}-#{dep_spec.version} depends on #{dep}"
    end
  end

  msg << 'If you remove this gem, these dependencies will not be met.'
  msg << 'Continue with Uninstall?'
  return ask_yes_no(msg.join("\n"), false)
end
dependencies_ok?(spec) click to toggle source
# File lib/rubygems/uninstaller.rb, line 286
def dependencies_ok?(spec)
  return true if @force_ignore

  deplist = Gem::DependencyList.from_specs
  deplist.ok_to_remove?(spec.full_name, @check_dev)
end
formatted_program_filename(filename) click to toggle source
# File lib/rubygems/uninstaller.rb, line 314
def formatted_program_filename(filename)
  # TODO perhaps the installer should leave a small manifest
  # of what it did for us to find rather than trying to recreate
  # it again.
  if @format_executable then
    require 'rubygems/installer'
    Gem::Installer.exec_format % File.basename(filename)
  else
    filename
  end
end
path_ok?(gem_dir, spec) click to toggle source

Is spec in gem_dir?

# File lib/rubygems/uninstaller.rb, line 279
def path_ok?(gem_dir, spec)
  full_path     = File.join gem_dir, 'gems', spec.full_name
  original_path = File.join gem_dir, 'gems', spec.original_name

  full_path == spec.full_gem_path || original_path == spec.full_gem_path
end
remove(spec) click to toggle source
spec

the spec of the gem to be uninstalled

list

the list of all such gems

Warning: this method modifies the list parameter. Once it has uninstalled a gem, it is removed from that list.

# File lib/rubygems/uninstaller.rb, line 235
def remove(spec)
  unless path_ok?(@gem_home, spec) or
         (@user_install and path_ok?(Gem.user_dir, spec)) then
    e = Gem::GemNotInHomeException.new              "Gem is not installed in directory #{@gem_home}"
    e.spec = spec

    raise e
  end

  raise Gem::FilePermissionError, spec.base_dir unless
    File.writable?(spec.base_dir)

  FileUtils.rm_rf spec.full_gem_path

  # TODO: should this be moved to spec?... I vote eww (also exists in docmgr)
  old_platform_name = [spec.name,
                       spec.version,
                       spec.original_platform].join '-'

  gemspec = spec.spec_file

  unless File.exist? gemspec then
    gemspec = File.join(File.dirname(gemspec), "#{old_platform_name}.gemspec")
  end

  FileUtils.rm_rf gemspec

  gem = spec.cache_file
  gem = File.join(spec.cache_dir, "#{old_platform_name}.gem") unless
    File.exist? gem

  FileUtils.rm_rf gem

  Gem::RDoc.new(spec).remove

  say "Successfully uninstalled #{spec.full_name}"

  Gem::Specification.remove_spec spec
end
remove_all(list) click to toggle source

Removes all gems in list.

NOTE: removes uninstalled gems from list.

# File lib/rubygems/uninstaller.rb, line 224
def remove_all(list)
  list.each { |spec| uninstall_gem spec }
end
remove_executables(spec) click to toggle source

Removes installed executables and batch files (windows only) for gemspec.

# File lib/rubygems/uninstaller.rb, line 170
def remove_executables(spec)
  return if spec.nil? or spec.executables.empty?

  executables = spec.executables.clone

  # Leave any executables created by other installed versions
  # of this gem installed.

  list = Gem::Specification.find_all { |s|
    s.name == spec.name && s.version != spec.version
  }

  list.each do |s|
    s.executables.each do |exe_name|
      executables.delete exe_name
    end
  end

  return if executables.empty?

  executables = executables.map { |exec| formatted_program_filename exec }

  remove = if @force_executables.nil? then
             ask_yes_no("Remove executables:\n" +
                        "\t#{executables.join ', '}\n\n" +
                        "in addition to the gem?",
                        true)
           else
             @force_executables
           end

  if remove then
    bin_dir = @bin_dir || Gem.bindir(spec.base_dir)

    raise Gem::FilePermissionError, bin_dir unless File.writable? bin_dir

    executables.each do |exe_name|
      say "Removing #{exe_name}"

      exe_file = File.join bin_dir, exe_name

      FileUtils.rm_f exe_file
      FileUtils.rm_f "#{exe_file}.bat"
    end
  else
    say "Executables and scripts will remain installed."
  end
end
uninstall() click to toggle source

Performs the uninstall of the gem. This removes the spec, the Gem directory, and the cached .gem file.

# File lib/rubygems/uninstaller.rb, line 74
def uninstall
  dependency = Gem::Dependency.new @gem, @version

  list = []

  dirs =
    Gem::Specification.dirs +
    [Gem::Specification.default_specifications_dir]

  Gem::Specification.each_spec dirs do |spec|
    next unless dependency.matches_spec? spec

    list << spec
  end

  default_specs, list = list.partition do |spec|
    spec.default_gem?
  end

  list, other_repo_specs = list.partition do |spec|
    @gem_home == spec.base_dir or
      (@user_install and spec.base_dir == Gem.user_dir)
  end

  if list.empty? then
    if other_repo_specs.empty?
      if default_specs.empty?
        raise Gem::InstallError, "gem #{@gem.inspect} is not installed"
      else
        message =
          "gem #{@gem.inspect} cannot be uninstalled " +
          "because it is a default gem"
        raise Gem::InstallError, message
      end
    end

    other_repos = other_repo_specs.map { |spec| spec.base_dir }.uniq

    message = ["#{@gem} is not installed in GEM_HOME, try:"]
    message.concat other_repos.map { |repo|
      "\tgem uninstall -i #{repo} #{@gem}"
    }

    raise Gem::InstallError, message.join("\n")
  elsif @force_all then
    remove_all list

  elsif list.size > 1 then
    gem_names = list.collect {|gem| gem.full_name} + ["All versions"]

    say
    _, index = choose_from_list "Select gem to uninstall:", gem_names

    if index == list.size then
      remove_all list
    elsif index >= 0 && index < list.size then
      uninstall_gem list[index]
    else
      say "Error: must enter a number [1-#{list.size+1}]"
    end
  else
    uninstall_gem list.first
  end
end
uninstall_gem(spec) click to toggle source

Uninstalls gem spec

# File lib/rubygems/uninstaller.rb, line 142
def uninstall_gem(spec)
  @spec = spec

  unless dependencies_ok? spec
    unless ask_if_ok(spec)
      raise Gem::DependencyRemovalException,
        "Uninstallation aborted due to dependent gem(s)"
    end
  end

  Gem.pre_uninstall_hooks.each do |hook|
    hook.call self
  end

  remove_executables @spec
  remove @spec

  Gem.post_uninstall_hooks.each do |hook|
    hook.call self
  end

  @spec = nil
end


class Gem::UnsatisfiableDepedencyError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::UnsatisfiableDepedencyError

Raised when a dependency requests a gem for which there is no spec.

In Files

  • lib/rubygems/dependency_resolver.rb

Parent

Gem::Exception

Attributes

dependency[R]

Public Class Methods

new(dep) click to toggle source
# File lib/rubygems/dependency_resolver.rb, line 32
def initialize(dep)
  super "unable to find any gem matching dependency '#{dep}'"

  @dependency = dep
end


module Gem::UserInteraction - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::UserInteraction

Make the default UI accessible without the “ui.” prefix. Classes including this module may use the interaction methods on the default UI directly. Classes may also reference the ui and ui= methods.

Example:

class X
  include Gem::UserInteraction

  def get_answer
    n = ask("What is the meaning of life?")
  end
end

In Files

  • lib/rubygems/user_interaction.rb

Included Modules

  • Gem::DefaultUserInteraction

Public Instance Methods

alert(*args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 87
def alert(*args)
  ui.alert(*args)
end
alert_error(*args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 91
def alert_error(*args)
  ui.alert_error(*args)
end
alert_warning(*args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 95
def alert_warning(*args)
  ui.alert_warning(*args)
end
ask(*args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 99
def ask(*args)
  ui.ask(*args)
end
ask_for_password(*args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 103
def ask_for_password(*args)
  ui.ask_for_password(*args)
end
ask_yes_no(*args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 107
def ask_yes_no(*args)
  ui.ask_yes_no(*args)
end
choose_from_list(*args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 111
def choose_from_list(*args)
  ui.choose_from_list(*args)
end
say(*args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 115
def say(*args)
  ui.say(*args)
end
terminate_interaction(*args) click to toggle source
# File lib/rubygems/user_interaction.rb, line 119
def terminate_interaction(*args)
  ui.terminate_interaction(*args)
end


class Gem::Validator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Validator

Validator performs various gem file and gem database validation

In Files

  • lib/rubygems/validator.rb

Parent

Object

Included Modules

  • Gem::UserInteraction

Constants

ErrorData

Public Class Methods

new() click to toggle source
# File lib/rubygems/validator.rb, line 17
def initialize
  require 'find'
end

Public Instance Methods

alien(gems=[]) click to toggle source

Checks the gem directory for the following potential inconsistencies/problems:

  • Checksum gem itself

  • For each file in each gem, check consistency of installed versions

  • Check for files that aren't part of the gem but are in the gems directory

  • 1 cache - 1 spec - 1 directory.

returns a hash of ErrorData objects, keyed on the problem gem's name.

# File lib/rubygems/validator.rb, line 81
def alien(gems=[])
  errors = Hash.new { |h,k| h[k] = {} }

  Gem::Specification.each do |spec|
    next unless gems.include? spec.name unless gems.empty?

    gem_name      = spec.file_name
    gem_path      = spec.cache_file
    spec_path     = spec.spec_file
    gem_directory = spec.full_gem_path

    unless File.directory? gem_directory then
      errors[gem_name][spec.full_name] =
        "Gem registered but doesn't exist at #{gem_directory}"
      next
    end

    unless File.exist? spec_path then
      errors[gem_name][spec_path] = "Spec file missing for installed gem"
    end

    begin
      verify_gem_file(gem_path)

      good, gone, unreadable = nil, nil, nil, nil

      open gem_path, Gem.binary_mode do |file|
        package = Gem::Package.new gem_path

        good, gone = package.contents.partition { |file_name|
          File.exist? File.join(gem_directory, file_name)
        }

        gone.sort.each do |path|
          errors[gem_name][path] = "Missing file"
        end

        good, unreadable = good.partition { |file_name|
          File.readable? File.join(gem_directory, file_name)
        }

        unreadable.sort.each do |path|
          errors[gem_name][path] = "Unreadable file"
        end

        good.each do |entry, data|
          begin
            next unless data # HACK `gem check -a mkrf`

            source = File.join gem_directory, entry['path']

            open source, Gem.binary_mode do |f|
              unless f.read == data then
                errors[gem_name][entry['path']] = "Modified from original"
              end
            end
          end
        end
      end

      installed_files = find_files_for_gem(gem_directory)
      extras = installed_files - good - unreadable

      extras.each do |extra|
        errors[gem_name][extra] = "Extra file"
      end
    rescue Gem::VerificationError => e
      errors[gem_name][gem_path] = e.message
    end
  end

  errors.each do |name, subhash|
    errors[name] = subhash.map do |path, msg|
      ErrorData.new path, msg
    end.sort
  end

  errors
end
verify_gem(gem_data) click to toggle source

Given a gem file's contents, validates against its own MD5 checksum

gem_data
String

Contents of the gem file

# File lib/rubygems/validator.rb, line 25
def verify_gem(gem_data)
  # TODO remove me? The code here only validate an MD5SUM that was
  # in some old formatted gems, but hasn't been for a long time.
end
verify_gem_file(gem_path) click to toggle source

Given the path to a gem file, validates against its own MD5 checksum

gem_path
String

Path to gem file

# File lib/rubygems/validator.rb, line 35
def verify_gem_file(gem_path)
  open gem_path, Gem.binary_mode do |file|
    gem_data = file.read
    verify_gem gem_data
  end
rescue Errno::ENOENT, Errno::EINVAL
  raise Gem::VerificationError, "missing gem file #{gem_path}"
end


class Gem::VerificationError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::VerificationError

In Files

  • lib/rubygems/exceptions.rb

Parent

Gem::Exception


class Gem::Version - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Gem::Version

This is needed for compatibility with older yaml gemspecs.

The Version class processes string versions into comparable values. A version string should normally be a series of numbers separated by periods. Each part (digits separated by periods) is considered its own number, and these are used for sorting. So for instance, 3.10 sorts higher than 3.2 because ten is greater than two.

If any part contains letters (currently only a-z are supported) then that version is considered prerelease. Versions with a prerelease part in the Nth part sort less than versions with N-1 parts. Prerelease parts are sorted alphabetically using the normal Ruby string sorting rules. If a prerelease part contains both letters and numbers, it will be broken into multiple parts to provide expected sort behavior (1.0.a10 becomes 1.0.a.10, and is greater than 1.0.a9).

Prereleases sort between real releases (newest to oldest):

  1. 1.0

  2. 1.0.b1

  3. 1.0.a.2

  4. 0.9

How Software Changes

Users expect to be able to specify a version constraint that gives them some reasonable expectation that new versions of a library will work with their software if the version constraint is true, and not work with their software if the version constraint is false. In other words, the perfect system will accept all compatible versions of the library and reject all incompatible versions.

Libraries change in 3 ways (well, more than 3, but stay focused here!).

  1. The change may be an implementation detail only and have no effect on the client software.

  2. The change may add new features, but do so in a way that client software written to an earlier version is still compatible.

  3. The change may change the public interface of the library in such a way that old software is no longer compatible.

Some examples are appropriate at this point. Suppose I have a Stack class that supports a push and a pop method.

Examples of Category 1 changes:

  • Switch from an array based implementation to a linked-list based implementation.

  • Provide an automatic (and transparent) backing store for large stacks.

Examples of Category 2 changes might be:

  • Add a depth method to return the current depth of the stack.

  • Add a top method that returns the current top of stack (without changing the stack).

  • Change push so that it returns the item pushed (previously it had no usable return value).

Examples of Category 3 changes might be:

  • Changes pop so that it no longer returns a value (you must use top to get the top of the stack).

  • Rename the methods to push_item and pop_item.

RubyGems Rational Versioning

  • Versions shall be represented by three non-negative integers, separated by periods (e.g. 3.1.4). The first integers is the “major” version number, the second integer is the “minor” version number, and the third integer is the “build” number.

  • A category 1 change (implementation detail) will increment the build number.

  • A category 2 change (backwards compatible) will increment the minor version number and reset the build number.

  • A category 3 change (incompatible) will increment the major build number and reset the minor and build numbers.

  • Any “public” release of a gem should have a different version. Normally that means incrementing the build number. This means a developer can generate builds all day long for himself, but as soon as he/she makes a public release, the version must be updated.

Examples

Let's work through a project lifecycle using our Stack example from above.

Version 0.0.1

The initial Stack class is release.

Version 0.0.2

Switched to a linked=list implementation because it is cooler.

Version 0.1.0

Added a depth method.

Version 1.0.0

Added top and made pop return nil (pop used to return the old top item).

Version 1.1.0

push now returns the value pushed (it used it return nil).

Version 1.1.1

Fixed a bug in the linked list implementation.

Version 1.1.2

Fixed a bug introduced in the last fix.

Client A needs a stack with basic push/pop capability. He writes to the original interface (no top), so his version constraint looks like:

gem 'stack', '~> 0.0'

Essentially, any version is OK with Client A. An incompatible change to the library will cause him grief, but he is willing to take the chance (we call Client A optimistic).

Client B is just like Client A except for two things: (1) He uses the depth method and (2) he is worried about future incompatibilities, so he writes his version constraint like this:

gem 'stack', '~> 0.1'

The depth method was introduced in version 0.1.0, so that version or anything later is fine, as long as the version stays below version 1.0 where incompatibilities are introduced. We call Client B pessimistic because he is worried about incompatible future changes (it is OK to be pessimistic!).

Preventing Version Catastrophe:

From: blog.zenspider.com/2008/10/rubygems-howto-preventing-cata.html

Let's say you're depending on the fnord gem version 2.y.z. If you specify your dependency as “>= 2.0.0” then, you're good, right? What happens if fnord 3.0 comes out and it isn't backwards compatible with 2.y.z? Your stuff will break as a result of using “>=”. The better route is to specify your dependency with an “approximate” version specifier (“~>”). They're a tad confusing, so here is how the dependency specifiers work:

Specification From  ... To (exclusive)
">= 3.0"      3.0   ... &infin;
"~> 3.0"      3.0   ... 4.0
"~> 3.0.0"    3.0.0 ... 3.1
"~> 3.5"      3.5   ... 4.0
"~> 3.5.0"    3.5.0 ... 3.6

In Files

  • lib/rubygems/requirement.rb
  • lib/rubygems/version.rb

Parent

Object

Included Modules

  • Comparable

Constants

Requirement

Attributes

to_s[R]

A string representation of this Version.

version[R]

A string representation of this Version.

Public Class Methods

correct?(version) click to toggle source

True if the version string matches RubyGems' requirements.

# File lib/rubygems/version.rb, line 162
def self.correct? version
  version.to_s =~ ANCHORED_VERSION_PATTERN
end
create(input) click to toggle source

REFACTOR: There's no real reason this should be separate from initialize.

# File lib/rubygems/version.rb, line 176
def self.create input
  if self === input then # check yourself before you wreck yourself
    input
  elsif input.nil? then
    nil
  else
    new input
  end
end
new(version) click to toggle source

Constructs a Version from the version string. A version string is a series of digits or ASCII letters separated by dots.

# File lib/rubygems/version.rb, line 190
def initialize version
  raise ArgumentError, "Malformed version number string #{version}" unless
    self.class.correct?(version)

  @version = version.to_s.dup.strip
end

Public Instance Methods

<=>(other) click to toggle source

Compares this version with other returning -1, 0, or 1 if the other version is larger, the same, or smaller than this one. Attempts to compare to something that's not a Gem::Version return nil.

# File lib/rubygems/version.rb, line 314
def <=> other
  return unless Gem::Version === other
  return 0 if @version == other.version

  lhsegments = segments
  rhsegments = other.segments

  lhsize = lhsegments.size
  rhsize = rhsegments.size
  limit  = (lhsize > rhsize ? lhsize : rhsize) - 1

  i = 0

  while i <= limit
    lhs, rhs = lhsegments[i] || 0, rhsegments[i] || 0
    i += 1

    next      if lhs == rhs
    return -1 if String  === lhs && Numeric === rhs
    return  1 if Numeric === lhs && String  === rhs

    return lhs <=> rhs
  end

  return 0
end
approximate_recommendation() click to toggle source

A recommended version for use with a ~> Requirement.

# File lib/rubygems/version.rb, line 298
def approximate_recommendation
  segments = self.segments.dup

  segments.pop    while segments.any? { |s| String === s }
  segments.pop    while segments.size > 2
  segments.push 0 while segments.size < 2

  "~> #{segments.join(".")}"
end
bump() click to toggle source

Return a new version object where the next to the last revision number is one greater (e.g., 5.3.1 => 5.4).

Pre-release (alpha) parts, e.g, 5.3.1.b.2 => 5.4, are ignored.

# File lib/rubygems/version.rb, line 203
def bump
  segments = self.segments.dup
  segments.pop while segments.any? { |s| String === s }
  segments.pop if segments.size > 1

  segments[-1] = segments[-1].succ
  self.class.new segments.join(".")
end
encode_with(coder) click to toggle source
# File lib/rubygems/version.rb, line 258
def encode_with coder
  coder.add 'version', @version
end
eql?(other) click to toggle source

A Version is only eql? to another version if it's specified to the same precision. Version “1.0” is not the same as version “1”.

# File lib/rubygems/version.rb, line 216
def eql? other
  self.class === other and @version == other.version
end
marshal_dump() click to toggle source

Dump only the raw version string, not the complete object. It's a string for backwards (RubyGems 1.3.5 and earlier) compatibility.

# File lib/rubygems/version.rb, line 236
def marshal_dump
  [version]
end
marshal_load(array) click to toggle source

Load custom marshal format. It's a string for backwards (RubyGems 1.3.5 and earlier) compatibility.

# File lib/rubygems/version.rb, line 244
def marshal_load array
  initialize array[0]
end
prerelease?() click to toggle source

A version is considered a prerelease if it contains a letter.

# File lib/rubygems/version.rb, line 265
def prerelease?
  @prerelease ||= !!(@version =~ /[a-zA-Z]/)
end
release() click to toggle source

The release for this version (e.g. 1.2.0.a -> 1.2.0). Non-prerelease versions return themselves.

# File lib/rubygems/version.rb, line 277
def release
  return self unless prerelease?

  segments = self.segments.dup
  segments.pop while segments.any? { |s| String === s }
  self.class.new segments.join('.')
end
to_yaml_properties() click to toggle source
# File lib/rubygems/version.rb, line 254
def to_yaml_properties
  ["@version"]
end
yaml_initialize(tag, map) click to toggle source
# File lib/rubygems/version.rb, line 248
def yaml_initialize(tag, map)
  @version = map['version']
  @segments = nil
  @hash = nil
end


module Gem::VersionOption - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Gem::VersionOption

Mixin methods for –version and –platform Gem::Command options.

In Files

  • lib/rubygems/version_option.rb

Public Instance Methods

add_platform_option(task = command, *wrap) click to toggle source

Add the –platform option to the option parser.

# File lib/rubygems/version_option.rb, line 17
def add_platform_option(task = command, *wrap)
  OptionParser.accept Gem::Platform do |value|
    if value == Gem::Platform::RUBY then
      value
    else
      Gem::Platform.new value
    end
  end

  add_option('--platform PLATFORM', Gem::Platform,
             "Specify the platform of gem to #{task}", *wrap) do
               |value, options|
    unless options[:added_platform] then
      Gem.platforms = [Gem::Platform::RUBY]
      options[:added_platform] = true
    end

    Gem.platforms << value unless Gem.platforms.include? value
  end
end
add_prerelease_option(*wrap) click to toggle source

Add the –prerelease option to the option parser.

# File lib/rubygems/version_option.rb, line 41
def add_prerelease_option(*wrap)
  add_option("--[no-]prerelease",
             "Allow prerelease versions of a gem", *wrap) do |value, options|
    options[:prerelease] = value
  end
end
add_version_option(task = command, *wrap) click to toggle source

Add the –version option to the option parser.

# File lib/rubygems/version_option.rb, line 51
def add_version_option(task = command, *wrap)
  OptionParser.accept Gem::Requirement do |value|
    Gem::Requirement.new value
  end

  add_option('-v', '--version VERSION', Gem::Requirement,
             "Specify version of gem to #{task}", *wrap) do
               |value, options|
    options[:version] = value
    options[:prerelease] = true if value.prerelease?
  end
end


class GetoptLong - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class GetoptLong

The GetoptLong class allows you to parse command line options similarly to the GNU getopt_long() C library call. Note, however, that GetoptLong is a pure Ruby implementation.

GetoptLong allows for POSIX-style options like --file as well as single letter options like -f

The empty option -- (two minus symbols) is used to end option processing. This can be particularly important if options have optional arguments.

Here is a simple example of usage:

require 'getoptlong'

opts = GetoptLong.new(
  [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
  [ '--repeat', '-n', GetoptLong::REQUIRED_ARGUMENT ],
  [ '--name', GetoptLong::OPTIONAL_ARGUMENT ]
)

dir = nil
name = nil
repetitions = 1
opts.each do |opt, arg|
  case opt
    when '--help'
      puts <<-EOF
hello [OPTION] ... DIR

-h, --help:
   show help

--repeat x, -n x:
   repeat x times

--name [name]:
   greet user by name, if name not supplied default is John

DIR: The directory in which to issue the greeting.
      EOF
    when '--repeat'
      repetitions = arg.to_i
    when '--name'
      if arg == ''
        name = 'John'
      else
        name = arg
      end
  end
end

if ARGV.length != 1
  puts "Missing dir argument (try --help)"
  exit 0
end

dir = ARGV.shift

Dir.chdir(dir)
for i in (1..repetitions)
  print "Hello"
  if name
    print ", #{name}"
  end
  puts
end

Example command line:

hello -n 6 --name -- /tmp

In Files

  • lib/getoptlong.rb

Parent

Object

Constants

ARGUMENT_FLAGS

Argument flags.

ORDERINGS

Orderings.

STATUS_TERMINATED

Attributes

error[R]

Examine whether an option processing is failed.

error?[R]

Examine whether an option processing is failed.

ordering[R]

Return ordering.

quiet[RW]

Set/Unset `quiet' mode.

quiet?[RW]

Set/Unset `quiet' mode.

Public Class Methods

new(*arguments) click to toggle source

Set up option processing.

The options to support are passed to new() as an array of arrays. Each sub-array contains any number of String option names which carry the same meaning, and one of the following flags:

GetoptLong::NO_ARGUMENT

Option does not take an argument.

GetoptLong::REQUIRED_ARGUMENT

Option always takes an argument.

GetoptLong::OPTIONAL_ARGUMENT

Option may or may not take an argument.

The first option name is considered to be the preferred (canonical) name. Other than that, the elements of each sub-array can be in any order.

# File lib/getoptlong.rb, line 128
def initialize(*arguments)
  #
  # Current ordering.
  #
  if ENV.include?('POSIXLY_CORRECT')
    @ordering = REQUIRE_ORDER
  else
    @ordering = PERMUTE
  end

  #
  # Hash table of option names.
  # Keys of the table are option names, and their values are canonical
  # names of the options.
  #
  @canonical_names = Hash.new

  #
  # Hash table of argument flags.
  # Keys of the table are option names, and their values are argument
  # flags of the options.
  #
  @argument_flags = Hash.new

  #
  # Whether error messages are output to $stderr.
  #
  @quiet = FALSE

  #
  # Status code.
  #
  @status = STATUS_YET

  #
  # Error code.
  #
  @error = nil

  #
  # Error message.
  #
  @error_message = nil

  #
  # Rest of catenated short options.
  #
  @rest_singles = ''

  #
  # List of non-option-arguments.
  # Append them to ARGV when option processing is terminated.
  #
  @non_option_arguments = Array.new

  if 0 < arguments.length
    set_options(*arguments)
  end
end

Public Instance Methods

each() { |option_name, option_argument| ... } click to toggle source

Iterator version of `get'.

The block is called repeatedly with two arguments: The first is the option name. The second is the argument which followed it (if any). Example: ('–opt', 'value')

The option name is always converted to the first (preferred) name given in the original options to ::new.

# File lib/getoptlong.rb, line 600
def each
  loop do
    option_name, option_argument = get_option
    break if option_name == nil
    yield option_name, option_argument
  end
end
Also aliased as: each_option
each_option() click to toggle source

`#each_option' is an alias of `each'.

Alias for: each
error_message() click to toggle source

Return the appropriate error message in POSIX-defined format. If no error has occurred, returns nil.

# File lib/getoptlong.rb, line 411
def error_message
  return @error_message
end
get() click to toggle source

Get next option name and its argument, as an Array of two elements.

The option name is always converted to the first (preferred) name given in the original options to ::new.

Example: ['–option', 'value']

Returns nil if the processing is complete (as determined by STATUS_TERMINATED).

# File lib/getoptlong.rb, line 426
def get
  option_name, option_argument = nil, ''

  #
  # Check status.
  #
  return nil if @error != nil
  case @status
  when STATUS_YET
    @status = STATUS_STARTED
  when STATUS_TERMINATED
    return nil
  end

  #
  # Get next option argument.
  #
  if 0 < @rest_singles.length
    argument = '-' + @rest_singles
  elsif (ARGV.length == 0)
    terminate
    return nil
  elsif @ordering == PERMUTE
    while 0 < ARGV.length && ARGV[0] !~ /^-./
      @non_option_arguments.push(ARGV.shift)
    end
    if ARGV.length == 0
      terminate
      return nil
    end
    argument = ARGV.shift
  elsif @ordering == REQUIRE_ORDER
    if (ARGV[0] !~ /^-./)
      terminate
      return nil
    end
    argument = ARGV.shift
  else
    argument = ARGV.shift
  end

  #
  # Check the special argument `--'.
  # `--' indicates the end of the option list.
  #
  if argument == '--' && @rest_singles.length == 0
    terminate
    return nil
  end

  #
  # Check for long and short options.
  #
  if argument =~ /^(--[^=]+)/ && @rest_singles.length == 0
    #
    # This is a long style option, which start with `--'.
    #
    pattern = $1
    if @canonical_names.include?(pattern)
      option_name = pattern
    else
      #
      # The option `option_name' is not registered in `@canonical_names'.
      # It may be an abbreviated.
      #
      matches = []
      @canonical_names.each_key do |key|
        if key.index(pattern) == 0
          option_name = key
          matches << key
        end
      end
      if 2 <= matches.length
        set_error(AmbiguousOption, "option `#{argument}' is ambiguous between #{matches.join(', ')}")
      elsif matches.length == 0
        set_error(InvalidOption, "unrecognized option `#{argument}'")
      end
    end

    #
    # Check an argument to the option.
    #
    if @argument_flags[option_name] == REQUIRED_ARGUMENT
      if argument =~ /=(.*)$/
        option_argument = $1
      elsif 0 < ARGV.length
        option_argument = ARGV.shift
      else
        set_error(MissingArgument,
                  "option `#{argument}' requires an argument")
      end
    elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
      if argument =~ /=(.*)$/
        option_argument = $1
      elsif 0 < ARGV.length && ARGV[0] !~ /^-./
        option_argument = ARGV.shift
      else
        option_argument = ''
      end
    elsif argument =~ /=(.*)$/
      set_error(NeedlessArgument,
                "option `#{option_name}' doesn't allow an argument")
    end

  elsif argument =~ /^(-(.))(.*)/
    #
    # This is a short style option, which start with `-' (not `--').
    # Short options may be catenated (e.g. `-l -g' is equivalent to
    # `-lg').
    #
    option_name, ch, @rest_singles = $1, $2, $3

    if @canonical_names.include?(option_name)
      #
      # The option `option_name' is found in `@canonical_names'.
      # Check its argument.
      #
      if @argument_flags[option_name] == REQUIRED_ARGUMENT
        if 0 < @rest_singles.length
          option_argument = @rest_singles
          @rest_singles = ''
        elsif 0 < ARGV.length
          option_argument = ARGV.shift
        else
          # 1003.2 specifies the format of this message.
          set_error(MissingArgument, "option requires an argument -- #{ch}")
        end
      elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
        if 0 < @rest_singles.length
          option_argument = @rest_singles
          @rest_singles = ''
        elsif 0 < ARGV.length && ARGV[0] !~ /^-./
          option_argument = ARGV.shift
        else
          option_argument = ''
        end
      end
    else
      #
      # This is an invalid option.
      # 1003.2 specifies the format of this message.
      #
      if ENV.include?('POSIXLY_CORRECT')
        set_error(InvalidOption, "invalid option -- #{ch}")
      else
        set_error(InvalidOption, "invalid option -- #{ch}")
      end
    end
  else
    #
    # This is a non-option argument.
    # Only RETURN_IN_ORDER falled into here.
    #
    return '', argument
  end

  return @canonical_names[option_name], option_argument
end
Also aliased as: get_option
get_option() click to toggle source

`#get_option' is an alias of `get'.

Alias for: get
ordering=(ordering) click to toggle source

Set the handling of the ordering of options and arguments. A RuntimeError is raised if option processing has already started.

The supplied value must be a member of GetoptLong::ORDERINGS. It alters the processing of options as follows:

REQUIRE_ORDER :

Options are required to occur before non-options.

Processing of options ends as soon as a word is encountered that has not been preceded by an appropriate option flag.

For example, if -a and -b are options which do not take arguments, parsing command line arguments of '-a one -b two' would result in 'one', '-b', 'two' being left in ARGV, and only ('-a', '') being processed as an option/arg pair.

This is the default ordering, if the environment variable POSIXLY_CORRECT is set. (This is for compatibility with GNU getopt_long.)

PERMUTE :

Options can occur anywhere in the command line parsed. This is the default behavior.

Every sequence of words which can be interpreted as an option (with or without argument) is treated as an option; non-option words are skipped.

For example, if -a does not require an argument and -b optionally takes an argument, parsing '-a one -b two three' would result in ('-a','') and ('-b', 'two') being processed as option/arg pairs, and 'one','three' being left in ARGV.

If the ordering is set to PERMUTE but the environment variable POSIXLY_CORRECT is set, REQUIRE_ORDER is used instead. This is for compatibility with GNU getopt_long.

RETURN_IN_ORDER :

All words on the command line are processed as options. Words not preceded by a short or long option flag are passed as arguments with an option of '' (empty string).

For example, if -a requires an argument but -b does not, a command line of '-a one -b two three' would result in option/arg pairs of ('-a', 'one') ('-b', ''), ('', 'two'), ('', 'three') being processed.

# File lib/getoptlong.rb, line 237
def ordering=(ordering)
  #
  # The method is failed if option processing has already started.
  #
  if @status != STATUS_YET
    set_error(ArgumentError, "argument error")
    raise RuntimeError,
      "invoke ordering=, but option processing has already started"
  end

  #
  # Check ordering.
  #
  if !ORDERINGS.include?(ordering)
    raise ArgumentError, "invalid ordering `#{ordering}'"
  end
  if ordering == PERMUTE && ENV.include?('POSIXLY_CORRECT')
    @ordering = REQUIRE_ORDER
  else
    @ordering = ordering
  end
end
set_options(*arguments) click to toggle source

Set options. Takes the same argument as ::new.

Raises a RuntimeError if option processing has already started.

# File lib/getoptlong.rb, line 270
def set_options(*arguments)
  #
  # The method is failed if option processing has already started.
  #
  if @status != STATUS_YET
    raise RuntimeError,
      "invoke set_options, but option processing has already started"
  end

  #
  # Clear tables of option names and argument flags.
  #
  @canonical_names.clear
  @argument_flags.clear

  arguments.each do |arg|
    if !arg.is_a?(Array)
     raise ArgumentError, "the option list contains non-Array argument"
    end

    #
    # Find an argument flag and it set to `argument_flag'.
    #
    argument_flag = nil
    arg.each do |i|
      if ARGUMENT_FLAGS.include?(i)
        if argument_flag != nil
          raise ArgumentError, "too many argument-flags"
        end
        argument_flag = i
      end
    end

    raise ArgumentError, "no argument-flag" if argument_flag == nil

    canonical_name = nil
    arg.each do |i|
      #
      # Check an option name.
      #
      next if i == argument_flag
      begin
        if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/
          raise ArgumentError, "an invalid option `#{i}'"
        end
        if (@canonical_names.include?(i))
          raise ArgumentError, "option redefined `#{i}'"
        end
      rescue
        @canonical_names.clear
        @argument_flags.clear
        raise
      end

      #
      # Register the option (`i') to the `@canonical_names' and
      # `@canonical_names' Hashes.
      #
      if canonical_name == nil
        canonical_name = i
      end
      @canonical_names[i] = canonical_name
      @argument_flags[i] = argument_flag
    end
    raise ArgumentError, "no option name" if canonical_name == nil
  end
  return self
end
terminate() click to toggle source

Explicitly terminate option processing.

# File lib/getoptlong.rb, line 357
def terminate
  return nil if @status == STATUS_TERMINATED
  raise RuntimeError, "an error has occurred" if @error != nil

  @status = STATUS_TERMINATED
  @non_option_arguments.reverse_each do |argument|
    ARGV.unshift(argument)
  end

  @canonical_names = nil
  @argument_flags = nil
  @rest_singles = nil
  @non_option_arguments = nil

  return self
end
terminated?() click to toggle source

Returns true if option processing has terminated, false otherwise.

# File lib/getoptlong.rb, line 377
def terminated?
  return @status == STATUS_TERMINATED
end

Protected Instance Methods

set_error(type, message) click to toggle source

Set an error (a protected method).

# File lib/getoptlong.rb, line 384
def set_error(type, message)
  $stderr.print("#{$0}: #{message}\n") if !@quiet

  @error = type
  @error_message = message
  @canonical_names = nil
  @argument_flags = nil
  @rest_singles = nil
  @non_option_arguments = nil

  raise type, message
end


class GetoptLong::AmbiguousOption - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class GetoptLong::AmbiguousOption

In Files

  • lib/getoptlong.rb

Parent

GetoptLong::Error


class GetoptLong::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class GetoptLong::Error

Error types.

In Files

  • lib/getoptlong.rb

Parent

StandardError


class GetoptLong::InvalidOption - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class GetoptLong::InvalidOption

In Files

  • lib/getoptlong.rb

Parent

GetoptLong::Error


class GetoptLong::MissingArgument - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class GetoptLong::MissingArgument

In Files

  • lib/getoptlong.rb

Parent

GetoptLong::Error


class GetoptLong::NeedlessArgument - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class GetoptLong::NeedlessArgument

In Files

  • lib/getoptlong.rb

Parent

GetoptLong::Error


class Hash - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Hash

In Files

  • lib/pp.rb

Parent

Object

Public Instance Methods

pretty_print(q) click to toggle source
# File lib/pp.rb, line 342
def pretty_print(q)
  q.pp_hash self
end
pretty_print_cycle(q) click to toggle source
# File lib/pp.rb, line 346
def pretty_print_cycle(q)
  q.text(empty? ? '{}' : '{...}')
end


class HttpServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class HttpServer

Implements a simple HTTP-server by using John W. Small's (jsmall@laser.net) ruby-generic-server: GServer.

In Files

  • lib/xmlrpc/httpserver.rb

Parent

GServer

Constants

CRLF
DEFAULT_HEADER

Default header for the server name

HTTP_PROTO
SERVER_NAME
StatusCodeMapping

Mapping of status codes and error messages

Public Class Methods

new(handle_obj, port = 8080, host = DEFAULT_HOST, maxConnections = 4, stdlog = $stdout, audit = true, debug = true) click to toggle source

handle_obj specifies the object, that receives calls from request_handler and ip_auth_handler

# File lib/xmlrpc/httpserver.rb, line 16
def initialize(handle_obj, port = 8080, host = DEFAULT_HOST, maxConnections = 4,
               stdlog = $stdout, audit = true, debug = true)
  @handler = handle_obj
  super(port, host, maxConnections, stdlog, audit, debug)
end

Private Instance Methods

http_date( aTime ) click to toggle source

Returns a string which represents the time as rfc1123-date of HTTP-date

# File lib/xmlrpc/httpserver.rb, line 115
def http_date( aTime ) # :doc:
  aTime.gmtime.strftime( "%a, %d %b %Y %H:%M:%S GMT" )
end
http_header(header=nil) click to toggle source

Generates a Hash with the HTTP headers

# File lib/xmlrpc/httpserver.rb, line 104
def http_header(header=nil) # :doc:
  new_header = Table.new(DEFAULT_HEADER)
  new_header.update(header) unless header.nil?

  new_header["Connection"] = "close"
  new_header["Date"]       = http_date(Time.now)

  new_header
end
http_resp(status_code, status_message=nil, header=nil, body=nil) click to toggle source

Returns a string which includes the status code message as, http headers, and body for the response.

# File lib/xmlrpc/httpserver.rb, line 121
def http_resp(status_code, status_message=nil, header=nil, body=nil) # :doc:
  status_message ||= StatusCodeMapping[status_code]

  str = ""
  str << "#{HTTP_PROTO} #{status_code} #{status_message}" << CRLF
  http_header(header).writeTo(str)
  str << CRLF
  str << body unless body.nil?
  str
end
serve(io) click to toggle source

Handles the HTTP request and writes the response back to the client, io.

If an Exception is raised while handling the request, the client will receive a 500 “Internal Server Error” message.

# File lib/xmlrpc/httpserver.rb, line 136
def serve(io) # :doc:
  # perform IP authentification
  unless @handler.ip_auth_handler(io)
    io << http_resp(403, "Forbidden")
    return
  end

  # parse first line
  if io.gets =~ /^(\S+)\s+(\S+)\s+(\S+)/
    request = Request.new(io, $1, $2, $3)
  else
    io << http_resp(400, "Bad Request")
    return
  end

  # parse HTTP headers
  while (line=io.gets) !~ /^(\n|\r)/
    if line =~ /^([\w-]+):\s*(.*)$/
      request.header[$1] = $2.strip
    end
  end

  io.binmode
  response = Response.new

  # execute request handler
  @handler.request_handler(request, response)

  # write response back to the client
  io << http_resp(response.status, response.status_message,
                  response.header, response.body)

rescue Exception
  io << http_resp(500, "Internal Server Error")
end


class HttpServer::Request - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class HttpServer::Request

In Files

  • lib/xmlrpc/httpserver.rb

Parent

Object

Attributes

data[R]
header[R]
method[R]
path[R]
proto[R]

Public Class Methods

new(data, method=nil, path=nil, proto=nil) click to toggle source
# File lib/xmlrpc/httpserver.rb, line 46
def initialize(data, method=nil, path=nil, proto=nil)
  @header, @data = Table.new, data
  @method, @path, @proto = method, path, proto
end

Public Instance Methods

content_length() click to toggle source
# File lib/xmlrpc/httpserver.rb, line 51
def content_length
  len = @header['Content-Length']
  return nil if len.nil?
  return len.to_i
end


class HttpServer::Response - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class HttpServer::Response

In Files

  • lib/xmlrpc/httpserver.rb

Parent

Object

Attributes

body[RW]
header[R]
status[RW]
status_message[RW]

Public Class Methods

new(status=200) click to toggle source
# File lib/xmlrpc/httpserver.rb, line 63
def initialize(status=200)
  @status = status
  @status_message = nil
  @header = Table.new
end


class HttpServer::Table - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class HttpServer::Table

A case-insensitive Hash class for HTTP header

In Files

  • lib/xmlrpc/httpserver.rb

Parent

Object

Included Modules

  • Enumerable

Public Class Methods

new(hash={}) click to toggle source
# File lib/xmlrpc/httpserver.rb, line 74
def initialize(hash={})
  @hash = hash
  update(hash)
end

Public Instance Methods

[](key) click to toggle source
# File lib/xmlrpc/httpserver.rb, line 79
def [](key)
  @hash[key.to_s.capitalize]
end
[]=(key, value) click to toggle source
# File lib/xmlrpc/httpserver.rb, line 83
def []=(key, value)
  @hash[key.to_s.capitalize] = value
end
each() { |capitalize, v| ... } click to toggle source
# File lib/xmlrpc/httpserver.rb, line 92
def each
  @hash.each {|k,v| yield k.capitalize, v }
end
update(hash) click to toggle source
# File lib/xmlrpc/httpserver.rb, line 87
def update(hash)
  hash.each {|k,v| self[k] = v}
  self
end
writeTo(port) click to toggle source

Output the Hash table for the HTTP header

# File lib/xmlrpc/httpserver.rb, line 97
def writeTo(port)
  each { |k,v| port << "#{k}: #{v}" << CRLF }
end


class IO - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IO

Expect library adds the IO instance method expect, which does similar act to tcl's expect extension.

In order to use this method, you must require expect:

require 'expect'

Please see expect for usage.

In Files

  • lib/scanf.rb
  • ext/io/console/console.c
  • ext/io/wait/wait.c
  • ext/pty/lib/expect.rb

Parent

Object

Public Class Methods

console → #<File:/dev/tty> click to toggle source

Returns an File instance opened console.

You must require 'io/console' to use this method.

static VALUE
console_dev(VALUE klass)
{
    VALUE con = 0;
    rb_io_t *fptr;

    if (klass == rb_cIO) klass = rb_cFile;
    if (rb_const_defined(klass, id_console)) {
        con = rb_const_get(klass, id_console);
        if (RB_TYPE_P(con, T_FILE)) {
            if ((fptr = RFILE(con)->fptr) && GetReadFD(fptr) != -1)
                return con;
        }
        rb_mod_remove_const(klass, ID2SYM(id_console));
    }
    {
        VALUE args[2];
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H || defined HAVE_SGTTY_H
# define CONSOLE_DEVICE "/dev/tty"
#elif defined _WIN32
# define CONSOLE_DEVICE "con$"
# define CONSOLE_DEVICE_FOR_READING "conin$"
# define CONSOLE_DEVICE_FOR_WRITING "conout$"
#endif
#ifndef CONSOLE_DEVICE_FOR_READING
# define CONSOLE_DEVICE_FOR_READING CONSOLE_DEVICE
#endif
#ifdef CONSOLE_DEVICE_FOR_WRITING
        VALUE out;
        rb_io_t *ofptr;
#endif
        int fd;

#ifdef CONSOLE_DEVICE_FOR_WRITING
        fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0);
        if (fd < 0) return Qnil;
        rb_update_max_fd(fd);
        args[1] = INT2FIX(O_WRONLY);
        args[0] = INT2NUM(fd);
        out = rb_class_new_instance(2, args, klass);
#endif
        fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0);
        if (fd < 0) {
#ifdef CONSOLE_DEVICE_FOR_WRITING
            rb_io_close(out);
#endif
            return Qnil;
        }
        rb_update_max_fd(fd);
        args[1] = INT2FIX(O_RDWR);
        args[0] = INT2NUM(fd);
        con = rb_class_new_instance(2, args, klass);
        GetOpenFile(con, fptr);
        fptr->pathv = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE));
#ifdef CONSOLE_DEVICE_FOR_WRITING
        GetOpenFile(out, ofptr);
# ifdef HAVE_RB_IO_GET_WRITE_IO
        ofptr->pathv = fptr->pathv;
        fptr->tied_io_for_writing = out;
# else
        fptr->f2 = ofptr->f;
        ofptr->f = 0;
# endif
        ofptr->mode |= FMODE_SYNC;
#endif
        fptr->mode |= FMODE_SYNC;
        rb_const_set(klass, id_console, con);
    }
    return con;
}

Public Instance Methods

cooked {|io| } click to toggle source

Yields self within cooked mode.

STDIN.cooked(&:gets)

will read and return a line with echo back and line editing.

You must require 'io/console' to use this method.

static VALUE
console_cooked(VALUE io)
{
    return ttymode(io, rb_yield, set_cookedmode, NULL);
}
cooked! click to toggle source

Enables cooked mode.

If the terminal mode needs to be back, use io.cooked { … }.

You must require 'io/console' to use this method.

static VALUE
console_set_cooked(VALUE io)
{
    conmode t;
    rb_io_t *fptr;
    int fd;

    GetOpenFile(io, fptr);
    fd = GetReadFD(fptr);
    if (!getattr(fd, &t)) rb_sys_fail(0);
    set_cookedmode(&t, NULL);
    if (!setattr(fd, &t)) rb_sys_fail(0);
    return io;
}
echo = flag click to toggle source

Enables/disables echo back. On some platforms, all combinations of this flags and raw/cooked mode may not be valid.

You must require 'io/console' to use this method.

static VALUE
console_set_echo(VALUE io, VALUE f)
{
    conmode t;
    rb_io_t *fptr;
    int fd;

    GetOpenFile(io, fptr);
    fd = GetReadFD(fptr);
    if (!getattr(fd, &t)) rb_sys_fail(0);
    if (RTEST(f))
        set_echo(&t, NULL);
    else
        set_noecho(&t, NULL);
    if (!setattr(fd, &t)) rb_sys_fail(0);
    return io;
}
echo? → true or false click to toggle source

Returns true if echo back is enabled.

You must require 'io/console' to use this method.

static VALUE
console_echo_p(VALUE io)
{
    conmode t;
    rb_io_t *fptr;
    int fd;

    GetOpenFile(io, fptr);
    fd = GetReadFD(fptr);
    if (!getattr(fd, &t)) rb_sys_fail(0);
    return echo_p(&t) ? Qtrue : Qfalse;
}
IO#expect(pattern,timeout=9999999) → Array click to toggle source
IO#expect(pattern,timeout=9999999) { |result| ... } → nil

Reads from the IO until the given pattern matches or the timeout is over.

It returns an array with the read buffer, followed by the matches. If a block is given, the result is yielded to the block and returns nil.

When called without a block, it waits until the input that matches the given pattern is obtained from the IO or the time specified as the timeout passes. An array is returned when the pattern is obtained from the IO. The first element of the array is the entire string obtained from the IO until the pattern matches, followed by elements indicating which the pattern which matched to the anchor in the regular expression.

The optional timeout parameter defines, in seconds, the total time to wait for the pattern. If the timeout expires or eof is found, nil is returned or yielded. However, the buffer in a timeout session is kept for the next expect call. The default timeout is 9999999 seconds.

# File ext/pty/lib/expect.rb, line 32
def expect(pat,timeout=9999999)
  buf = ''
  case pat
  when String
    e_pat = Regexp.new(Regexp.quote(pat))
  when Regexp
    e_pat = pat
  else
    raise TypeError, "unsupported pattern class: #{pat.class}"
  end
  @unusedBuf ||= ''
  while true
    if not @unusedBuf.empty?
      c = @unusedBuf.slice!(0).chr
    elsif !IO.select([self],nil,nil,timeout) or eof? then
      result = nil
      @unusedBuf = buf
      break
    else
      c = getc.chr
    end
    buf << c
    if $expect_verbose
      STDOUT.print c
      STDOUT.flush
    end
    if mat=e_pat.match(buf) then
      result = [buf,*mat.to_a[1..-1]]
      break
    end
  end
  if block_given? then
    yield result
  else
    return result
  end
  nil
end
getch(min: nil, time: nil) → char click to toggle source

Reads and returns a character in raw mode.

You must require 'io/console' to use this method.

static VALUE
console_getch(int argc, VALUE *argv, VALUE io)
{
    rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
    return ttymode(io, getc_call, set_rawmode, optp);
}
iflush click to toggle source

Flushes input buffer in kernel.

You must require 'io/console' to use this method.

static VALUE
console_iflush(VALUE io)
{
    rb_io_t *fptr;
    int fd;

    GetOpenFile(io, fptr);
    fd = GetReadFD(fptr);
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
    if (tcflush(fd, TCIFLUSH)) rb_sys_fail(0);
#endif
    return io;
}
ioflush click to toggle source

Flushes input and output buffers in kernel.

You must require 'io/console' to use this method.

static VALUE
console_ioflush(VALUE io)
{
    rb_io_t *fptr;
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
    int fd1, fd2;
#endif

    GetOpenFile(io, fptr);
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
    fd1 = GetReadFD(fptr);
    fd2 = GetWriteFD(fptr);
    if (fd2 != -1 && fd1 != fd2) {
        if (tcflush(fd1, TCIFLUSH)) rb_sys_fail(0);
        if (tcflush(fd2, TCOFLUSH)) rb_sys_fail(0);
    }
    else {
        if (tcflush(fd1, TCIOFLUSH)) rb_sys_fail(0);
    }
#endif
    return io;
}
noecho {|io| } click to toggle source

Yields self with disabling echo back.

STDIN.noecho(&:gets)

will read and return a line without echo back.

You must require 'io/console' to use this method.

static VALUE
console_noecho(VALUE io)
{
    return ttymode(io, rb_yield, set_noecho, NULL);
}
nread → int click to toggle source

Returns number of bytes that can be read without blocking. Returns zero if no information available.

static VALUE
io_nread(VALUE io)
{
    rb_io_t *fptr;
    int len;
    ioctl_arg n;

    GetOpenFile(io, fptr);
    rb_io_check_readable(fptr);
    len = rb_io_read_pending(fptr);
    if (len > 0) return len;
    if (!FIONREAD_POSSIBLE_P(fptr->fd)) return INT2FIX(0);
    if (ioctl(fptr->fd, FIONREAD, &n)) return INT2FIX(0);
    if (n > 0) return ioctl_arg2num(n);
    return INT2FIX(0);
}
oflush click to toggle source

Flushes output buffer in kernel.

You must require 'io/console' to use this method.

static VALUE
console_oflush(VALUE io)
{
    rb_io_t *fptr;
    int fd;

    GetOpenFile(io, fptr);
    fd = GetWriteFD(fptr);
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
    if (tcflush(fd, TCOFLUSH)) rb_sys_fail(0);
#endif
    return io;
}
raw(min: nil, time: nil) {|io| } click to toggle source

Yields self within raw mode.

STDIN.raw(&:gets)

will read and return a line without echo back and line editing.

You must require 'io/console' to use this method.

static VALUE
console_raw(int argc, VALUE *argv, VALUE io)
{
    rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
    return ttymode(io, rb_yield, set_rawmode, optp);
}
raw!(min: nil, time: nil) click to toggle source

Enables raw mode.

If the terminal mode needs to be back, use io.raw { … }.

You must require 'io/console' to use this method.

static VALUE
console_set_raw(int argc, VALUE *argv, VALUE io)
{
    conmode t;
    rb_io_t *fptr;
    int fd;
    rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);

    GetOpenFile(io, fptr);
    fd = GetReadFD(fptr);
    if (!getattr(fd, &t)) rb_sys_fail(0);
    set_rawmode(&t, optp);
    if (!setattr(fd, &t)) rb_sys_fail(0);
    return io;
}
ready? → true, false or nil click to toggle source

Returns true if input available without blocking, or false. Returns nil if no information available.

static VALUE
io_ready_p(VALUE io)
{
    rb_io_t *fptr;
    ioctl_arg n;

    GetOpenFile(io, fptr);
    rb_io_check_readable(fptr);
    if (rb_io_read_pending(fptr)) return Qtrue;
    if (!FIONREAD_POSSIBLE_P(fptr->fd)) return Qnil;
    if (ioctl(fptr->fd, FIONREAD, &n)) return Qnil;
    if (n > 0) return Qtrue;
    return Qfalse;
}
scanf(str) { |current_match| ... } click to toggle source

Scans the current string until the match is exhausted, yielding each match as it is encountered in the string. A block is not necessary though, as the results will simply be aggregated into the final array.

"123 456".block_scanf("%d")
# => [123, 456]

If a block is given, the value from that is returned from the yield is added to an output array.

"123 456".block_scanf("%d) do |digit,| # the ',' unpacks the Array
  digit + 100
end
# => [223, 556]

See Scanf for details on creating a format string.

You will need to require 'scanf' to use use #scanf.

# File lib/scanf.rb, line 614
def scanf(str,&b) #:yield: current_match
  return block_scanf(str,&b) if b
  return [] unless str.size > 0

  start_position = pos rescue 0
  matched_so_far = 0
  source_buffer = ""
  result_buffer = []
  final_result = []

  fstr = Scanf::FormatString.new(str)

  loop do
    if eof || (tty? &&! fstr.match(source_buffer))
      final_result.concat(result_buffer)
      break
    end

    source_buffer << gets

    current_match = fstr.match(source_buffer)

    spec = fstr.last_spec_tried

    if spec.matched
      if spec.mid_match?
        result_buffer.replace(current_match)
        next
      end

    elsif (fstr.matched_count == fstr.spec_count - 1)
      if /\A\s*\z/.match(fstr.string_left)
        break if spec.count_space?
        result_buffer.replace(current_match)
        next
      end
    end

    final_result.concat(current_match)

    matched_so_far += source_buffer.size
    source_buffer.replace(fstr.string_left)
    matched_so_far -= source_buffer.size
    break if fstr.last_spec
    fstr.prune
  end
  seek(start_position + matched_so_far, IO::SEEK_SET) rescue Errno::ESPIPE
  soak_up_spaces if fstr.last_spec && fstr.space

  return final_result
end
wait → IO, true, false or nil click to toggle source
wait(timeout) → IO, true, false or nil

Waits until input is available or times out and returns self or nil when EOF is reached.

static VALUE
io_wait_readable(int argc, VALUE *argv, VALUE io)
{
    rb_io_t *fptr;
    int i;
    ioctl_arg n;
    VALUE timeout;
    struct timeval timerec;
    struct timeval *tv;

    GetOpenFile(io, fptr);
    rb_io_check_readable(fptr);
    rb_scan_args(argc, argv, "01", &timeout);
    if (NIL_P(timeout)) {
        tv = NULL;
    }
    else {
        timerec = rb_time_interval(timeout);
        tv = &timerec;
    }

    if (rb_io_read_pending(fptr)) return Qtrue;
    if (!FIONREAD_POSSIBLE_P(fptr->fd)) return Qfalse;
    i = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, tv);
    if (i < 0)
        rb_sys_fail(0);
    rb_io_check_closed(fptr);
    if (ioctl(fptr->fd, FIONREAD, &n)) rb_sys_fail(0);
    if (n > 0) return io;
    return Qnil;
}
wait → IO, true, false or nil click to toggle source
wait(timeout) → IO, true, false or nil

Waits until input is available or times out and returns self or nil when EOF is reached.

static VALUE
io_wait_readable(int argc, VALUE *argv, VALUE io)
{
    rb_io_t *fptr;
    int i;
    ioctl_arg n;
    VALUE timeout;
    struct timeval timerec;
    struct timeval *tv;

    GetOpenFile(io, fptr);
    rb_io_check_readable(fptr);
    rb_scan_args(argc, argv, "01", &timeout);
    if (NIL_P(timeout)) {
        tv = NULL;
    }
    else {
        timerec = rb_time_interval(timeout);
        tv = &timerec;
    }

    if (rb_io_read_pending(fptr)) return Qtrue;
    if (!FIONREAD_POSSIBLE_P(fptr->fd)) return Qfalse;
    i = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, tv);
    if (i < 0)
        rb_sys_fail(0);
    rb_io_check_closed(fptr);
    if (ioctl(fptr->fd, FIONREAD, &n)) rb_sys_fail(0);
    if (n > 0) return io;
    return Qnil;
}
wait_writable → IO click to toggle source
wait_writable(timeout) → IO or nil

Waits until IO writable is available or times out and returns self or nil when EOF is reached.

static VALUE
io_wait_writable(int argc, VALUE *argv, VALUE io)
{
    rb_io_t *fptr;
    int i;
    VALUE timeout;
    struct timeval timerec;
    struct timeval *tv;

    GetOpenFile(io, fptr);
    rb_io_check_writable(fptr);
    rb_scan_args(argc, argv, "01", &timeout);
    if (NIL_P(timeout)) {
        tv = NULL;
    }
    else {
        timerec = rb_time_interval(timeout);
        tv = &timerec;
    }

    i = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_OUT, tv);
    if (i < 0)
        rb_sys_fail(0);
    rb_io_check_closed(fptr);
    if (i & RB_WAITFD_OUT)
        return io;
    return Qnil;
}
winsize → [rows, columns] click to toggle source

Returns console size.

You must require 'io/console' to use this method.

static VALUE
console_winsize(VALUE io)
{
    rb_io_t *fptr;
    int fd;
    rb_console_size_t ws;

    GetOpenFile(io, fptr);
    fd = GetWriteFD(fptr);
    if (!getwinsize(fd, &ws)) rb_sys_fail(0);
    return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws)));
}
winsize = [rows, columns] click to toggle source

Tries to set console size. The effect depends on the platform and the running environment.

You must require 'io/console' to use this method.

static VALUE
console_set_winsize(VALUE io, VALUE size)
{
    rb_io_t *fptr;
    rb_console_size_t ws;
#if defined _WIN32
    HANDLE wh;
    int newrow, newcol;
#endif
    VALUE row, col, xpixel, ypixel;
#if defined TIOCSWINSZ
    int fd;
#endif

    GetOpenFile(io, fptr);
    size = rb_Array(size);
    rb_scan_args((int)RARRAY_LEN(size), RARRAY_PTR(size), "22",
                &row, &col, &xpixel, &ypixel);
#if defined TIOCSWINSZ
    fd = GetWriteFD(fptr);
    ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0;
#define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
    SET(row);
    SET(col);
    SET(xpixel);
    SET(ypixel);
#undef SET
    if (!setwinsize(fd, &ws)) rb_sys_fail(0);
#elif defined _WIN32
    wh = (HANDLE)rb_w32_get_osfhandle(GetReadFD(fptr));
    newrow = (SHORT)NUM2UINT(row);
    newcol = (SHORT)NUM2UINT(col);
    if (!getwinsize(GetReadFD(fptr), &ws)) {
        rb_sys_fail("GetConsoleScreenBufferInfo");
    }
    if ((ws.dwSize.X < newcol && (ws.dwSize.X = newcol, 1)) ||
        (ws.dwSize.Y < newrow && (ws.dwSize.Y = newrow, 1))) {
        if (!(SetConsoleScreenBufferSize(wh, ws.dwSize) || SET_LAST_ERROR)) {
            rb_sys_fail("SetConsoleScreenBufferInfo");
        }
    }
    ws.srWindow.Left = 0;
    ws.srWindow.Top = 0;
    ws.srWindow.Right = newcol;
    ws.srWindow.Bottom = newrow;
    if (!(SetConsoleWindowInfo(wh, FALSE, &ws.srWindow) || SET_LAST_ERROR)) {
        rb_sys_fail("SetConsoleWindowInfo");
    }
#endif
    return io;
}


module IO::readable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module IO::readable

In Files

  • lib/scanf.rb

Public Instance Methods

getch(*args) click to toggle source
static VALUE
io_getch(int argc, VALUE *argv, VALUE io)
{
    return rb_funcall2(io, rb_intern("getc"), argc, argv);
}
sysread(integer[, outbuf]) → string click to toggle source

Similar to read, but raises EOFError at end of string instead of returning nil, as well as Object#sysread does.

static VALUE
strio_sysread(int argc, VALUE *argv, VALUE self)
{
    VALUE val = rb_funcall2(self, rb_intern("read"), argc, argv);
    if (NIL_P(val)) {
        rb_eof_error();
    }
    return val;
}
readbyte → fixnum click to toggle source

See IO#readbyte.

static VALUE
strio_readbyte(VALUE self)
{
    VALUE c = rb_funcall2(self, rb_intern("getbyte"), 0, 0);
    if (NIL_P(c)) rb_eof_error();
    return c;
}
readchar → string click to toggle source

See IO#readchar.

static VALUE
strio_readchar(VALUE self)
{
    VALUE c = rb_funcall2(self, rb_intern("getc"), 0, 0);
    if (NIL_P(c)) rb_eof_error();
    return c;
}
readline(sep=$/) → string click to toggle source
readline(limit) → string or nil
readline(sep, limit) → string or nil

See IO#readline.

static VALUE
strio_readline(int argc, VALUE *argv, VALUE self)
{
    VALUE line = rb_funcall2(self, rb_intern("gets"), argc, argv);
    if (NIL_P(line)) rb_eof_error();
    return line;
}
sysread(integer[, outbuf]) → string click to toggle source

Similar to read, but raises EOFError at end of string instead of returning nil, as well as Object#sysread does.

static VALUE
strio_sysread(int argc, VALUE *argv, VALUE self)
{
    VALUE val = rb_funcall2(self, rb_intern("read"), argc, argv);
    if (NIL_P(val)) {
        rb_eof_error();
    }
    return val;
}
sysread(integer[, outbuf]) → string click to toggle source

Similar to read, but raises EOFError at end of string instead of returning nil, as well as Object#sysread does.

static VALUE
strio_sysread(int argc, VALUE *argv, VALUE self)
{
    VALUE val = rb_funcall2(self, rb_intern("read"), argc, argv);
    if (NIL_P(val)) {
        rb_eof_error();
    }
    return val;
}


module IO::writable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module IO::writable

In Files

  • lib/scanf.rb

Public Instance Methods

strio << obj → strio click to toggle source

See IO#<<.

#define strio_addstr rb_io_addstr
print() → nil click to toggle source
print(obj, ...) → nil

See IO#print.

#define strio_print rb_io_print
printf(format_string [, obj, ...] ) → nil click to toggle source

See IO#printf.

#define strio_printf rb_io_printf
puts(obj, ...) → nil click to toggle source

See IO#puts.

#define strio_puts rb_io_puts


class IPAddr - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IPAddr

IPAddr provides a set of methods to manipulate an IP address. Both IPv4 and IPv6 are supported.

Example

require 'ipaddr'

ipaddr1 = IPAddr.new "3ffe:505:2::1"

p ipaddr1                   #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>

p ipaddr1.to_s              #=> "3ffe:505:2::1"

ipaddr2 = ipaddr1.mask(48)  #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>

p ipaddr2.to_s              #=> "3ffe:505:2::"

ipaddr3 = IPAddr.new "192.168.2.0/24"

p ipaddr3                   #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>

In Files

  • lib/ipaddr.rb

Parent

Object

Included Modules

  • Comparable

Constants

IN4MASK

32 bit mask for IPv4

IN6FORMAT

Format string for IPv6

IN6MASK

128 bit mask for IPv4

RE_IPV4ADDRLIKE

Regexp internally used for parsing IPv4 address.

RE_IPV6ADDRLIKE_COMPRESSED

Regexp internally used for parsing IPv6 address.

RE_IPV6ADDRLIKE_FULL

Regexp internally used for parsing IPv6 address.

Attributes

family[R]

Returns the address family of this IP address.

Public Class Methods

new(addr = '::', family = Socket::AF_UNSPEC) click to toggle source

Creates a new ipaddr object either from a human readable IP address representation in string, or from a packed in_addr value followed by an address family.

In the former case, the following are the valid formats that will be recognized: “address”, “address/prefixlen” and “address/mask”, where IPv6 address may be enclosed in square brackets (`[' and `]'). If a prefixlen or a mask is specified, it returns a masked IP address. Although the address family is determined automatically from a specified string, you can specify one explicitly by the optional second argument.

Otherwise an IP address is generated from a packed in_addr value and an address family.

The IPAddr class defines many methods and operators, and some of those, such as &, |, include? and ==, accept a string, or a packed in_addr value instead of an IPAddr object.

# File lib/ipaddr.rb, line 467
def initialize(addr = '::', family = Socket::AF_UNSPEC)
  if !addr.kind_of?(String)
    case family
    when Socket::AF_INET, Socket::AF_INET6
      set(addr.to_i, family)
      @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
      return
    when Socket::AF_UNSPEC
      raise AddressFamilyError, "address family must be specified"
    else
      raise AddressFamilyError, "unsupported address family: #{family}"
    end
  end
  prefix, prefixlen = addr.split('/')
  if prefix =~ /^\[(.*)\]$/
    prefix = $1
    family = Socket::AF_INET6
  end
  # It seems AI_NUMERICHOST doesn't do the job.
  #Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
  #                  Socket::AI_NUMERICHOST)
  @addr = @family = nil
  if family == Socket::AF_UNSPEC || family == Socket::AF_INET
    @addr = in_addr(prefix)
    if @addr
      @family = Socket::AF_INET
    end
  end
  if !@addr && (family == Socket::AF_UNSPEC || family == Socket::AF_INET6)
    @addr = in6_addr(prefix)
    @family = Socket::AF_INET6
  end
  if family != Socket::AF_UNSPEC && @family != family
    raise AddressFamilyError, "address family mismatch"
  end
  if prefixlen
    mask!(prefixlen)
  else
    @mask_addr = (@family == Socket::AF_INET) ? IN4MASK : IN6MASK
  end
end
new_ntoh(addr) click to toggle source

Creates a new ipaddr containing the given network byte ordered string form of an IP address.

# File lib/ipaddr.rb, line 105
def IPAddr::new_ntoh(addr)
  return IPAddr.new(IPAddr::ntop(addr))
end
ntop(addr) click to toggle source

Convert a network byte ordered string form of an IP address into human readable form.

# File lib/ipaddr.rb, line 111
def IPAddr::ntop(addr)
  case addr.size
  when 4
    s = addr.unpack('C4').join('.')
  when 16
    s = IN6FORMAT % addr.unpack('n8')
  else
    raise AddressFamilyError, "unsupported address family"
  end
  return s
end

Public Instance Methods

&(other) click to toggle source

Returns a new ipaddr built by bitwise AND.

# File lib/ipaddr.rb, line 124
def &(other)
  return self.clone.set(@addr & coerce_other(other).to_i)
end
<<(num) click to toggle source

Returns a new ipaddr built by bitwise left shift.

# File lib/ipaddr.rb, line 139
def <<(num)
  return self.clone.set(addr_mask(@addr << num))
end
<=>(other) click to toggle source

Compares the ipaddr with another.

# File lib/ipaddr.rb, line 335
def <=>(other)
  other = coerce_other(other)

  return nil if other.family != @family

  return @addr <=> other.to_i
end
==(other) click to toggle source

Returns true if two ipaddrs are equal.

# File lib/ipaddr.rb, line 149
def ==(other)
  other = coerce_other(other)
  return @family == other.family && @addr == other.to_i
end
===(other) click to toggle source
Alias for: include?
>>(num) click to toggle source

Returns a new ipaddr built by bitwise right-shift.

# File lib/ipaddr.rb, line 134
def >>(num)
  return self.clone.set(@addr >> num)
end
eql?(other) click to toggle source

Checks equality used by Hash.

# File lib/ipaddr.rb, line 345
def eql?(other)
  return self.class == other.class && self.hash == other.hash && self == other
end
hash() click to toggle source

Returns a hash value used by Hash, Set, and Array classes

# File lib/ipaddr.rb, line 350
def hash
  return ([@addr, @mask_addr].hash << 1) | (ipv4? ? 0 : 1)
end
hton() click to toggle source

Returns a network byte ordered string form of the IP address.

# File lib/ipaddr.rb, line 235
def hton
  case @family
  when Socket::AF_INET
    return [@addr].pack('N')
  when Socket::AF_INET6
    return (0..7).map { |i|
      (@addr >> (112 - 16 * i)) & 0xffff
    }.pack('n8')
  else
    raise AddressFamilyError, "unsupported address family"
  end
end
include?(other) click to toggle source

Returns true if the given ipaddr is in the range.

e.g.:

require 'ipaddr'
net1 = IPAddr.new("192.168.2.0/24")
net2 = IPAddr.new("192.168.2.100")
net3 = IPAddr.new("192.168.3.0")
p net1.include?(net2)     #=> true
p net1.include?(net3)     #=> false

# File lib/ipaddr.rb, line 169
def include?(other)
  other = coerce_other(other)
  if ipv4_mapped?
    if (@mask_addr >> 32) != 0xffffffffffffffffffffffff
      return false
    end
    mask_addr = (@mask_addr & IN4MASK)
    addr = (@addr & IN4MASK)
    family = Socket::AF_INET
  else
    mask_addr = @mask_addr
    addr = @addr
    family = @family
  end
  if other.ipv4_mapped?
    other_addr = (other.to_i & IN4MASK)
    other_family = Socket::AF_INET
  else
    other_addr = other.to_i
    other_family = other.family
  end

  if family != other_family
    return false
  end
  return ((addr & mask_addr) == (other_addr & mask_addr))
end
Also aliased as: ===
inspect() click to toggle source

Returns a string containing a human-readable representation of the ipaddr. (“#<IPAddr: family:address/mask>”)

# File lib/ipaddr.rb, line 372
def inspect
  case @family
  when Socket::AF_INET
    af = "IPv4"
  when Socket::AF_INET6
    af = "IPv6"
  else
    raise AddressFamilyError, "unsupported address family"
  end
  return sprintf("#<%s: %s:%s/%s>", self.class.name,
                 af, _to_string(@addr), _to_string(@mask_addr))
end
ip6_arpa() click to toggle source

Returns a string for DNS reverse lookup compatible with RFC3172.

# File lib/ipaddr.rb, line 314
def ip6_arpa
  if !ipv6?
    raise InvalidAddressError, "not an IPv6 address"
  end
  return _reverse + ".ip6.arpa"
end
ip6_int() click to toggle source

Returns a string for DNS reverse lookup compatible with RFC1886.

# File lib/ipaddr.rb, line 322
def ip6_int
  if !ipv6?
    raise InvalidAddressError, "not an IPv6 address"
  end
  return _reverse + ".ip6.int"
end
ipv4?() click to toggle source

Returns true if the ipaddr is an IPv4 address.

# File lib/ipaddr.rb, line 249
def ipv4?
  return @family == Socket::AF_INET
end
ipv4_compat() click to toggle source

Returns a new ipaddr built by converting the native IPv4 address into an IPv4-compatible IPv6 address.

# File lib/ipaddr.rb, line 283
def ipv4_compat
  if !ipv4?
    raise InvalidAddressError, "not an IPv4 address"
  end
  return self.clone.set(@addr, Socket::AF_INET6)
end
ipv4_compat?() click to toggle source

Returns true if the ipaddr is an IPv4-compatible IPv6 address.

# File lib/ipaddr.rb, line 264
def ipv4_compat?
  if !ipv6? || (@addr >> 32) != 0
    return false
  end
  a = (@addr & IN4MASK)
  return a != 0 && a != 1
end
ipv4_mapped() click to toggle source

Returns a new ipaddr built by converting the native IPv4 address into an IPv4-mapped IPv6 address.

# File lib/ipaddr.rb, line 274
def ipv4_mapped
  if !ipv4?
    raise InvalidAddressError, "not an IPv4 address"
  end
  return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
end
ipv4_mapped?() click to toggle source

Returns true if the ipaddr is an IPv4-mapped IPv6 address.

# File lib/ipaddr.rb, line 259
def ipv4_mapped?
  return ipv6? && (@addr >> 32) == 0xffff
end
ipv6?() click to toggle source

Returns true if the ipaddr is an IPv6 address.

# File lib/ipaddr.rb, line 254
def ipv6?
  return @family == Socket::AF_INET6
end
mask(prefixlen) click to toggle source

Returns a new ipaddr built by masking IP address with the given prefixlen/netmask. (e.g. 8, 64, “255.255.255.0”, etc.)

# File lib/ipaddr.rb, line 156
def mask(prefixlen)
  return self.clone.mask!(prefixlen)
end
native() click to toggle source

Returns a new ipaddr built by converting the IPv6 address into a native IPv4 address. If the IP address is not an IPv4-mapped or IPv4-compatible IPv6 address, returns self.

# File lib/ipaddr.rb, line 293
def native
  if !ipv4_mapped? && !ipv4_compat?
    return self
  end
  return self.clone.set(@addr & IN4MASK, Socket::AF_INET)
end
reverse() click to toggle source

Returns a string for DNS reverse lookup. It returns a string in RFC3172 form for an IPv6 address.

# File lib/ipaddr.rb, line 302
def reverse
  case @family
  when Socket::AF_INET
    return _reverse + ".in-addr.arpa"
  when Socket::AF_INET6
    return ip6_arpa
  else
    raise AddressFamilyError, "unsupported address family"
  end
end
succ() click to toggle source

Returns the successor to the ipaddr.

# File lib/ipaddr.rb, line 330
def succ
  return self.clone.set(@addr + 1, @family)
end
to_i() click to toggle source

Returns the integer representation of the ipaddr.

# File lib/ipaddr.rb, line 199
def to_i
  return @addr
end
to_range() click to toggle source

Creates a Range object for the network address.

# File lib/ipaddr.rb, line 355
def to_range
  begin_addr = (@addr & @mask_addr)

  case @family
  when Socket::AF_INET
    end_addr = (@addr | (IN4MASK ^ @mask_addr))
  when Socket::AF_INET6
    end_addr = (@addr | (IN6MASK ^ @mask_addr))
  else
    raise AddressFamilyError, "unsupported address family"
  end

  return clone.set(begin_addr, @family)..clone.set(end_addr, @family)
end
to_s() click to toggle source

Returns a string containing the IP address representation.

# File lib/ipaddr.rb, line 204
def to_s
  str = to_string
  return str if ipv4?

  str.gsub!(/\b0{1,3}([\da-f]+)\b/, '\1')
  loop do
    break if str.sub!(/\A0:0:0:0:0:0:0:0\z/, '::')
    break if str.sub!(/\b0:0:0:0:0:0:0\b/, ':')
    break if str.sub!(/\b0:0:0:0:0:0\b/, ':')
    break if str.sub!(/\b0:0:0:0:0\b/, ':')
    break if str.sub!(/\b0:0:0:0\b/, ':')
    break if str.sub!(/\b0:0:0\b/, ':')
    break if str.sub!(/\b0:0\b/, ':')
    break
  end
  str.sub!(/:{3,}/, '::')

  if /\A::(ffff:)?([\da-f]{1,4}):([\da-f]{1,4})\z/ =~ str
    str = sprintf('::%s%d.%d.%d.%d', $1, $2.hex / 256, $2.hex % 256, $3.hex / 256, $3.hex % 256)
  end

  str
end
to_string() click to toggle source

Returns a string containing the IP address representation in canonical form.

# File lib/ipaddr.rb, line 230
def to_string
  return _to_string(@addr)
end
|(other) click to toggle source

Returns a new ipaddr built by bitwise OR.

# File lib/ipaddr.rb, line 129
def |(other)
  return self.clone.set(@addr | coerce_other(other).to_i)
end
~() click to toggle source

Returns a new ipaddr built by bitwise negation.

# File lib/ipaddr.rb, line 144
def ~
  return self.clone.set(addr_mask(~@addr))
end

Protected Instance Methods

mask!(mask) click to toggle source

Set current netmask to given mask.

# File lib/ipaddr.rb, line 411
def mask!(mask)
  if mask.kind_of?(String)
    if mask =~ /^\d+$/
      prefixlen = mask.to_i
    else
      m = IPAddr.new(mask)
      if m.family != @family
        raise InvalidPrefixError, "address family is not same"
      end
      @mask_addr = m.to_i
      @addr &= @mask_addr
      return self
    end
  else
    prefixlen = mask
  end
  case @family
  when Socket::AF_INET
    if prefixlen < 0 || prefixlen > 32
      raise InvalidPrefixError, "invalid length"
    end
    masklen = 32 - prefixlen
    @mask_addr = ((IN4MASK >> masklen) << masklen)
  when Socket::AF_INET6
    if prefixlen < 0 || prefixlen > 128
      raise InvalidPrefixError, "invalid length"
    end
    masklen = 128 - prefixlen
    @mask_addr = ((IN6MASK >> masklen) << masklen)
  else
    raise AddressFamilyError, "unsupported address family"
  end
  @addr = ((@addr >> masklen) << masklen)
  return self
end
set(addr, *family) click to toggle source

Set +@addr+, the internal stored ip address, to given addr. The parameter addr is validated using the first family member, which is +Socket::AF_INET+ or +Socket::AF_INET6+.

# File lib/ipaddr.rb, line 390
def set(addr, *family)
  case family[0] ? family[0] : @family
  when Socket::AF_INET
    if addr < 0 || addr > IN4MASK
      raise InvalidAddressError, "invalid address"
    end
  when Socket::AF_INET6
    if addr < 0 || addr > IN6MASK
      raise InvalidAddressError, "invalid address"
    end
  else
    raise AddressFamilyError, "unsupported address family"
  end
  @addr = addr
  if family[0]
    @family = family[0]
  end
  return self
end


class IPAddr::AddressFamilyError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IPAddr::AddressFamilyError

Raised when the address family is invalid such as an address with an unsupported family, an address with an inconsistent family, or an address who's family cannot be determined.

In Files

  • lib/ipaddr.rb

Parent

IPAddr::Error


class IPAddr::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IPAddr::Error

Generic IPAddr related error. Exceptions raised in this class should inherit from Error.

In Files

  • lib/ipaddr.rb

Parent

ArgumentError


class IPAddr::InvalidAddressError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IPAddr::InvalidAddressError

Raised when the provided IP address is an invalid address.

In Files

  • lib/ipaddr.rb

Parent

IPAddr::Error


class IPAddr::InvalidPrefixError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IPAddr::InvalidPrefixError

Raised when the address is an invalid length.

In Files

  • lib/ipaddr.rb

Parent

IPAddr::InvalidAddressError


class IPSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IPSocket

IPSocket is the super class of TCPSocket and UDPSocket.

In Files

  • lib/ipaddr.rb
  • lib/resolv-replace.rb
  • ext/socket/ipsocket.c

Parent

BasicSocket

Public Class Methods

getaddress(s) click to toggle source

Returns a String based representation of a valid DNS hostname, IPv4 or IPv6 address.

IPSocket.getaddress 'localhost'         #=> "::1"
IPSocket.getaddress 'broadcasthost'     #=> "255.255.255.255"
IPSocket.getaddress 'www.ruby-lang.org' #=> "221.186.184.68"
IPSocket.getaddress 'www.ccc.de'        #=> "2a00:1328:e102:ccc0::122"

# File lib/ipaddr.rb, line 650
def getaddress(s)
  if valid_v6?(s)
    s
  else
    getaddress_orig(s)
  end
end
Also aliased as: getaddress_orig
getaddress_orig(s) click to toggle source
Alias for: getaddress

Public Instance Methods

addr([reverse_lookup]) → [address_family, port, hostname, numeric_address] click to toggle source

Returns the local address as an array which contains address_family, port, hostname and numeric_address.

If reverse_lookup is true or :hostname, hostname is obtained from numeric_address using reverse lookup. Or if it is false, or :numeric, hostname is same as numeric_address. Or if it is nil or ommitted, obeys to ipsocket.do_not_reverse_lookup. See Socket.getaddrinfo also.

TCPSocket.open("www.ruby-lang.org", 80) {|sock|
  p sock.addr #=> ["AF_INET", 49429, "hal", "192.168.0.128"]
  p sock.addr(true)  #=> ["AF_INET", 49429, "hal", "192.168.0.128"]
  p sock.addr(false) #=> ["AF_INET", 49429, "192.168.0.128", "192.168.0.128"]
  p sock.addr(:hostname)  #=> ["AF_INET", 49429, "hal", "192.168.0.128"]
  p sock.addr(:numeric)   #=> ["AF_INET", 49429, "192.168.0.128", "192.168.0.128"]
}

static VALUE
ip_addr(int argc, VALUE *argv, VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_storage addr;
    socklen_t len = (socklen_t)sizeof addr;
    int norevlookup;

    GetOpenFile(sock, fptr);

    if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup))
        norevlookup = fptr->mode & FMODE_NOREVLOOKUP;
    if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
        rb_sys_fail("getsockname(2)");
    return rsock_ipaddr((struct sockaddr*)&addr, len, norevlookup);
}
peeraddr([reverse_lookup]) → [address_family, port, hostname, numeric_address] click to toggle source

Returns the remote address as an array which contains address_family, port, hostname and numeric_address. It is defined for connection oriented socket such as TCPSocket.

If reverse_lookup is true or :hostname, hostname is obtained from numeric_address using reverse lookup. Or if it is false, or :numeric, hostname is same as numeric_address. Or if it is nil or ommitted, obeys to ipsocket.do_not_reverse_lookup. See Socket.getaddrinfo also.

TCPSocket.open("www.ruby-lang.org", 80) {|sock|
  p sock.peeraddr #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"]
  p sock.peeraddr(true)  #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"]
  p sock.peeraddr(false) #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"]
  p sock.peeraddr(:hostname) #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"]
  p sock.peeraddr(:numeric)  #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"]
}

static VALUE
ip_peeraddr(int argc, VALUE *argv, VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_storage addr;
    socklen_t len = (socklen_t)sizeof addr;
    int norevlookup;

    GetOpenFile(sock, fptr);

    if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup))
        norevlookup = fptr->mode & FMODE_NOREVLOOKUP;
    if (getpeername(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
        rb_sys_fail("getpeername(2)");
    return rsock_ipaddr((struct sockaddr*)&addr, len, norevlookup);
}
recvfrom(maxlen) → [mesg, ipaddr] click to toggle source
recvfrom(maxlen, flags) → [mesg, ipaddr]

Receives a message and return the message as a string and an address which the message come from.

maxlen is the maximum number of bytes to receive.

flags should be a bitwise OR of Socket::MSG_* constants.

ipaddr is same as IPSocket#{peeraddr,addr}.

u1 = UDPSocket.new
u1.bind("127.0.0.1", 4913)
u2 = UDPSocket.new
u2.send "uuuu", 0, "127.0.0.1", 4913
p u1.recvfrom(10) #=> ["uuuu", ["AF_INET", 33230, "localhost", "127.0.0.1"]]

static VALUE
ip_recvfrom(int argc, VALUE *argv, VALUE sock)
{
    return rsock_s_recvfrom(sock, argc, argv, RECV_IP);
}


module IRB - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module IRB

IRB stands for “interactive ruby” and is a tool to interactively execute ruby expressions read from the standard input.

The irb command from your shell will start the interpreter.

Usage

Use of irb is easy if you know ruby.

When executing irb, prompts are displayed as follows. Then, enter the ruby expression. An input is executed when it is syntactically complete.

$ irb
irb(main):001:0> 1+2
#=> 3
irb(main):002:0> class Foo
irb(main):003:1>  def foo
irb(main):004:2>    print 1
irb(main):005:2>  end
irb(main):006:1> end
#=> nil

The Readline extension module can be used with irb. Use of Readline is default if it's installed.

Command line options

Usage:  irb.rb [options] [programfile] [arguments]
  -f                Suppress read of ~/.irbrc
  -m                Bc mode (load mathn, fraction or matrix are available)
  -d                Set $DEBUG to true (same as `ruby -d')
  -r load-module    Same as `ruby -r'
  -I path           Specify $LOAD_PATH directory
  -U                Same as `ruby -U`
  -E enc            Same as `ruby -E`
  -w                Same as `ruby -w`
  -W[level=2]       Same as `ruby -W`
  --inspect         Use `inspect' for output (default except for bc mode)
  --noinspect       Don't use inspect for output
  --readline        Use Readline extension module
  --noreadline      Don't use Readline extension module
  --prompt prompt-mode
  --prompt-mode prompt-mode
                    Switch prompt mode. Pre-defined prompt modes are
                    `default', `simple', `xmp' and `inf-ruby'
  --inf-ruby-mode   Use prompt appropriate for inf-ruby-mode on emacs.
                    Suppresses --readline.
  --simple-prompt   Simple prompt mode
  --noprompt        No prompt mode
  --tracer          Display trace for each execution of commands.
  --back-trace-limit n
                    Display backtrace top n and tail n. The default
                    value is 16.
  --irb_debug n     Set internal debug level to n (not for popular use)
  -v, --version     Print the version of irb

Configuration

IRB reads from ~/.irbrc when it's invoked.

If ~/.irbrc doesn't exist, irb will try to read in the following order:

  • .irbrc

  • irb.rc

  • _irbrc

  • $irbrc

The following are alternatives to the command line options. To use them type as follows in an irb session:

IRB.conf[:IRB_NAME]="irb"
IRB.conf[:MATH_MODE]=false
IRB.conf[:INSPECT_MODE]=nil
IRB.conf[:IRB_RC] = nil
IRB.conf[:BACK_TRACE_LIMIT]=16
IRB.conf[:USE_LOADER] = false
IRB.conf[:USE_READLINE] = nil
IRB.conf[:USE_TRACER] = false
IRB.conf[:IGNORE_SIGINT] = true
IRB.conf[:IGNORE_EOF] = false
IRB.conf[:PROMPT_MODE] = :DEFALUT
IRB.conf[:PROMPT] = {...}
IRB.conf[:DEBUG_LEVEL]=0

Auto indentation

To enable auto-indent mode in irb, add the following to your .irbrc:

IRB.conf[:AUTO_INDENT] = true

Autocompletion

To enable autocompletion for irb, add the following to your .irbrc:

require 'irb/completion'

History

By default, irb disables history and will not store any commands you used.

If you want to enable history, add the following to your .irbrc:

IRB.conf[:SAVE_HISTORY] = 1000

This will now store the last 1000 commands in ~/.irb_history.

See IRB::Context#save_history= for more information.

Customizing the IRB Prompt

In order to customize the prompt, you can change the following Hash:

IRB.conf[:PROMPT]

This example can be used in your .irbrc

IRB.conf[:PROMPT][:MY_PROMPT] = { # name of prompt mode
  :AUTO_INDENT => true            # enables auto-indent mode
  :PROMPT_I => nil,               # normal prompt
  :PROMPT_S => nil,               # prompt for continuated strings
  :PROMPT_C => nil,               # prompt for continuated statement
  :RETURN => "    ==>%s\n"        # format to return value
}

IRB.conf[:PROMPT_MODE] = :MY_PROMPT

Or, invoke irb with the above prompt mode by:

irb --prompt my-prompt

Constants PROMPT_I, PROMPT_S and PROMPT_C specify the format. In the prompt specification, some special strings are available:

%N    # command name which is running
%m    # to_s of main object (self)
%M    # inspect of main object (self)
%l    # type of string(", ', /, ]), `]' is inner %w[...]
%NNi  # indent level. NN is degits and means as same as printf("%NNd").
      # It can be ommited
%NNn  # line number.
%%    # %

For instance, the default prompt mode is defined as follows:

IRB.conf[:PROMPT_MODE][:DEFAULT] = {
  :PROMPT_I => "%N(%m):%03n:%i> ",
  :PROMPT_S => "%N(%m):%03n:%i%l ",
  :PROMPT_C => "%N(%m):%03n:%i* ",
  :RETURN => "%s\n" # used to printf
}

irb comes with a number of available modes:

# :NULL:
#   :PROMPT_I:
#   :PROMPT_N:
#   :PROMPT_S:
#   :PROMPT_C:
#   :RETURN: |
#     %s
# :DEFAULT:
#   :PROMPT_I: ! '%N(%m):%03n:%i> '
#   :PROMPT_N: ! '%N(%m):%03n:%i> '
#   :PROMPT_S: ! '%N(%m):%03n:%i%l '
#   :PROMPT_C: ! '%N(%m):%03n:%i* '
#   :RETURN: |
#     => %s
# :CLASSIC:
#   :PROMPT_I: ! '%N(%m):%03n:%i> '
#   :PROMPT_N: ! '%N(%m):%03n:%i> '
#   :PROMPT_S: ! '%N(%m):%03n:%i%l '
#   :PROMPT_C: ! '%N(%m):%03n:%i* '
#   :RETURN: |
#     %s
# :SIMPLE:
#   :PROMPT_I: ! '>> '
#   :PROMPT_N: ! '>> '
#   :PROMPT_S:
#   :PROMPT_C: ! '?> '
#   :RETURN: |
#     => %s
# :INF_RUBY:
#   :PROMPT_I: ! '%N(%m):%03n:%i> '
#   :PROMPT_N:
#   :PROMPT_S:
#   :PROMPT_C:
#   :RETURN: |
#     %s
#   :AUTO_INDENT: true
# :XMP:
#   :PROMPT_I:
#   :PROMPT_N:
#   :PROMPT_S:
#   :PROMPT_C:
#   :RETURN: |2
#         ==>%s

Restrictions

Because irb evaluates input immediately after it is syntactically complete, the results may be slightly different than directly using ruby.

IRB Sessions

IRB has a special feature, that allows you to manage many sessions at once.

You can create new sessions with Irb.irb, and get a list of current sessions with the jobs command in the prompt.

Commands

JobManager provides commands to handle the current sessions:

jobs    # List of current sessions
fg      # Switches to the session of the given number
kill    # Kills the session with the given number

The exit command, or ::irb_exit, will quit the current session and call any exit hooks with ::irb_at_exit.

A few commands for loading files within the session are also available:

source

Loads a given file in the current session and displays the source lines, see IRB::IrbLoader#source_file

irb_load

Loads the given file similarly to Kernel#load, see IRB::IrbLoader#irb_load

irb_require

Loads the given file similarly to Kernel#require

Configuration

The command line options, or ::conf, specify the default behavior of Irb.irb.

On the other hand, each conf in IRB is used to individually configure ::irb.

If a proc is set for ::conf, its will be invoked after execution of that proc with the context of the current session as its argument. Each session can be configured using this mechanism.

Session variables

There are a few variables in every Irb session that can come in handy:

_

The value command executed, as a local variable

__

The history of evaluated commands

__[line_no]

Returns the evaluation value at the given line number, line_no. If line_no is a negative, the return value line_no many lines before the most recent return value.

Example using IRB Sessions

# invoke a new session
irb(main):001:0> irb
# list open sessions
irb.1(main):001:0> jobs
  #0->irb on main (#<Thread:0x400fb7e4> : stop)
  #1->irb#1 on main (#<Thread:0x40125d64> : running)

# change the active session
irb.1(main):002:0> fg 0
# define class Foo in top-level session
irb(main):002:0> class Foo;end
# invoke a new session with the context of Foo
irb(main):003:0> irb Foo
# define Foo#foo
irb.2(Foo):001:0> def foo
irb.2(Foo):002:1>   print 1
irb.2(Foo):003:1> end

# change the active session
irb.2(Foo):004:0> fg 0
# list open sessions
irb(main):004:0> jobs
  #0->irb on main (#<Thread:0x400fb7e4> : running)
  #1->irb#1 on main (#<Thread:0x40125d64> : stop)
  #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
# check if Foo#foo is available
irb(main):005:0> Foo.instance_methods #=> [:foo, ...]

# change the active sesssion
irb(main):006:0> fg 2
# define Foo#bar in the context of Foo
irb.2(Foo):005:0> def bar
irb.2(Foo):006:1>  print "bar"
irb.2(Foo):007:1> end
irb.2(Foo):010:0>  Foo.instance_methods #=> [:bar, :foo, ...]

# change the active session
irb.2(Foo):011:0> fg 0
irb(main):007:0> f = Foo.new  #=> #<Foo:0x4010af3c>
# invoke a new session with the context of f (instance of Foo)
irb(main):008:0> irb f
# list open sessions
irb.3(<Foo:0x4010af3c>):001:0> jobs
  #0->irb on main (#<Thread:0x400fb7e4> : stop)
  #1->irb#1 on main (#<Thread:0x40125d64> : stop)
  #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
  #3->irb#3 on #<Foo:0x4010af3c> (#<Thread:0x4010a1e0> : running)
# evaluate f.foo
irb.3(<Foo:0x4010af3c>):002:0> foo #=> 1 => nil
# evaluate f.bar
irb.3(<Foo:0x4010af3c>):003:0> bar #=> bar => nil
# kill jobs 1, 2, and 3
irb.3(<Foo:0x4010af3c>):004:0> kill 1, 2, 3
# list open sesssions, should only include main session
irb(main):009:0> jobs
  #0->irb on main (#<Thread:0x400fb7e4> : running)
# quit irb
irb(main):010:0> exit

In Files

  • lib/irb/cmd/chws.rb
  • lib/irb/cmd/fork.rb
  • lib/irb/cmd/help.rb
  • lib/irb/cmd/load.rb
  • lib/irb/cmd/nop.rb
  • lib/irb/cmd/pushws.rb
  • lib/irb/cmd/subirb.rb
  • lib/irb/completion.rb
  • lib/irb/context.rb
  • lib/irb/ext/change-ws.rb
  • lib/irb/ext/history.rb
  • lib/irb/ext/loader.rb
  • lib/irb/ext/math-mode.rb
  • lib/irb/ext/multi-irb.rb
  • lib/irb/ext/save-history.rb
  • lib/irb/ext/tracer.rb
  • lib/irb/ext/use-loader.rb
  • lib/irb/ext/workspaces.rb
  • lib/irb/extend-command.rb
  • lib/irb/frame.rb
  • lib/irb/help.rb
  • lib/irb/init.rb
  • lib/irb/input-method.rb
  • lib/irb/inspector.rb
  • lib/irb/lc/error.rb
  • lib/irb/lc/ja/encoding_aliases.rb
  • lib/irb/lc/ja/error.rb
  • lib/irb/locale.rb
  • lib/irb/magic-file.rb
  • lib/irb/notifier.rb
  • lib/irb/output-method.rb
  • lib/irb/slex.rb
  • lib/irb/version.rb
  • lib/irb/workspace.rb
  • lib/irb.rb

Public Class Methods

CurrentContext() click to toggle source

The current Context in this session

# File lib/irb/ext/multi-irb.rb, line 183
def IRB.CurrentContext
  IRB.JobManager.irb(Thread.current).context
end
JobManager() click to toggle source

The current JobManager in the session

# File lib/irb/ext/multi-irb.rb, line 178
def IRB.JobManager
  @JobManager
end
conf() click to toggle source

Displays current configuration.

Modifing the configuration is achieved by sending a message to ::conf.

See Configuration at IRB for more information.

# File lib/irb.rb, line 353
def IRB.conf
  @CONF
end
initialize_tracer() click to toggle source

initialize tracing function

# File lib/irb/ext/tracer.rb, line 16
def IRB.initialize_tracer
  Tracer.verbose = false
  Tracer.add_filter {
    |event, file, line, id, binding, *rests|
    /^#{Regexp.quote(@CONF[:IRB_LIB_PATH])}/ !~ file and
      File::basename(file) != "irb.rb"
  }
end
irb(file = nil, *main) click to toggle source

Creates a new IRB session, see IRB::Irb.new.

The optional file argument is given to IRB::Context.new, along with the workspace created with the remaining arguments, see IRB::WorkSpace.new

# File lib/irb/ext/multi-irb.rb, line 191
def IRB.irb(file = nil, *main)
  workspace = WorkSpace.new(*main)
  parent_thread = Thread.current
  Thread.start do
    begin
      irb = Irb.new(workspace, file)
    rescue
      print "Subirb can't start with context(self): ", workspace.main.inspect, "\n"
      print "return to main irb\n"
      Thread.pass
      Thread.main.wakeup
      Thread.exit
    end
    @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
    @JobManager.insert(irb)
    @JobManager.current_job = irb
    begin
      system_exit = false
      catch(:IRB_EXIT) do
        irb.eval_input
      end
    rescue SystemExit
      system_exit = true
      raise
      #fail
    ensure
      unless system_exit
        @JobManager.delete(irb)
        if @JobManager.current_job == irb
          if parent_thread.alive?
            @JobManager.current_job = @JobManager.irb(parent_thread)
            parent_thread.run
          else
            @JobManager.current_job = @JobManager.main_irb
            @JobManager.main_thread.run
          end
        end
      end
    end
  end
  Thread.stop
  @JobManager.current_job = @JobManager.irb(Thread.current)
end
irb_abort(irb, exception = Abort) click to toggle source

Aborts then interrupts irb.

Will raise an Abort exception, or the given exception.

# File lib/irb.rb, line 418
def IRB.irb_abort(irb, exception = Abort)
  if defined? Thread
    irb.context.thread.raise exception, "abort then interrupt!"
  else
    raise exception, "abort then interrupt!"
  end
end
irb_at_exit() click to toggle source

Calls each event hook of ::conf when the current session quits.

# File lib/irb.rb, line 406
def IRB.irb_at_exit
  @CONF[:AT_EXIT].each{|hook| hook.call}
end
irb_exit(irb, ret) click to toggle source

Quits irb

# File lib/irb.rb, line 411
def IRB.irb_exit(irb, ret)
  throw :IRB_EXIT, ret
end
print_usage() click to toggle source

Outputs the irb help message, see Command line options at IRB.

# File lib/irb/help.rb, line 16
def IRB.print_usage
  lc = IRB.conf[:LC_MESSAGES]
  path = lc.find("irb/help-message")
  space_line = false
  IRB::MagicFile.open(path){|f|
    f.each_line do |l|
      if /^\s*$/ =~ l
        lc.puts l unless space_line
        space_line = true
        next
      end
      space_line = false

      l.sub!(/#.*$/, "")
        next if /^\s*$/ =~ l
      lc.puts l
    end
  }
end
start(ap_path = nil) click to toggle source

Initializes IRB and creates a new Irb.irb object at the TOPLEVEL_BINDING

# File lib/irb.rb, line 377
  def IRB.start(ap_path = nil)
    $0 = File::basename(ap_path, ".rb") if ap_path

    IRB.setup(ap_path)

    if @CONF[:SCRIPT]
      irb = Irb.new(nil, @CONF[:SCRIPT])
    else
      irb = Irb.new
    end

    @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
    @CONF[:MAIN_CONTEXT] = irb.context

    trap("SIGINT") do
      irb.signal_handle
    end

    begin
      catch(:IRB_EXIT) do
        irb.eval_input
      end
    ensure
      irb_at_exit
    end
#    print "\n"
  end
version() click to toggle source

Returns the current version of IRB, including release version and last updated date.

# File lib/irb.rb, line 359
def IRB.version
  if v = @CONF[:VERSION] then return v end

  require "irb/version"
  rv = @RELEASE_VERSION.sub(/\.0/, "")
  @CONF[:VERSION] = format("irb %s(%s)", rv, @LAST_UPDATE_DATE)
end


class IRB::Abort - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::Abort

An exception raised by IRB.irb_abort

In Files

  • lib/irb.rb

Parent

Exception


class IRB::Context - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::Context

A class that wraps the current state of the irb session, including the configuration of IRB.conf.

In Files

  • lib/irb/context.rb
  • lib/irb/ext/change-ws.rb
  • lib/irb/ext/history.rb
  • lib/irb/ext/math-mode.rb
  • lib/irb/ext/save-history.rb
  • lib/irb/ext/tracer.rb
  • lib/irb/ext/use-loader.rb
  • lib/irb/ext/workspaces.rb

Parent

Object

Attributes

ap_name[RW]

A copy of the default IRB.conf[:AP_NAME]

auto_indent_mode[RW]

Can be either the default IRB.conf[:AUTO_INDENT], or the mode set by prompt_mode=

To enable auto-indentation in irb:

IRB.conf[:AUTO_INDENT] = true

or

irb_context.auto_indent_mode = true

or

IRB.CurrentContext.auto_indent_mode = true

See Configuration at IRB for more information.

back_trace_limit[RW]

The limit of backtrace lines displayed as top n and tail n.

The default value is 16.

Can also be set using the --back-trace-limit command line option.

See Command line options at IRB for more command line options.

debug_level[R]

The debug level of irb

See debug_level= for more information.

echo[RW]

Whether to echo the return value to output or not.

Uses IRB.conf if available, or defaults to true.

puts "hello"
# hello
#=> nil
IRB.CurrentContext.echo = false
puts "omg"
# omg
echo?[RW]

Whether to echo the return value to output or not.

Uses IRB.conf if available, or defaults to true.

puts "hello"
# hello
#=> nil
IRB.CurrentContext.echo = false
puts "omg"
# omg
eval_history[R]

The command result history limit.

ignore_eof[RW]

Whether ^D (control-d) will be ignored or not.

If set to false, ^D will quit irb.

ignore_eof?[RW]

Whether ^D (control-d) will be ignored or not.

If set to false, ^D will quit irb.

ignore_sigint[RW]

Whether ^C (control-c) will be ignored or not.

If set to false, ^C will quit irb.

If set to true,

  • during input: cancel input then return to top level.

  • during execute: abandon current execution.

ignore_sigint?[RW]

Whether ^C (control-c) will be ignored or not.

If set to false, ^C will quit irb.

If set to true,

  • during input: cancel input then return to top level.

  • during execute: abandon current execution.

inspect_mode[R]

A copy of the default IRB.conf[:INSPECT_MODE]

io[RW]

The current input method

Can be either StdioInputMethod, ReadlineInputMethod, FileInputMethod or other specified when the context is created. See ::new for more information on input_method.

irb[RW]

Current irb session

irb_name[RW]

Can be either name from IRB.conf[:IRB_NAME], or the number of the current job set by JobManager, such as irb#2

irb_path[RW]

Can be either the irb_name surrounded by parenthesis, or the input_method passed to ::new

last_value[R]

The return value of the last statement evaluated.

load_modules[RW]

A copy of the default IRB.conf[:LOAD_MODULES]

math?[R]

Returns whether bc mode is enabled.

See math_mode=

math_mode[R]

Returns whether bc mode is enabled.

See math_mode=

prompt_c[RW]

IRB prompt for continuated statement (e.g. immediately after an if)

See IRB for more information.

prompt_i[RW]

Standard IRB prompt

See IRB for more information.

prompt_mode[R]

A copy of the default IRB.conf[:PROMPT_MODE]

prompt_n[RW]

See Customizing the IRB Prompt at IRB for more information.

prompt_s[RW]

IRB prompt for continuated strings

See IRB for more information.

rc[RW]

A copy of the default IRB.conf[:RC]

rc?[RW]

A copy of the default IRB.conf[:RC]

return_format[RW]

The format of the return statement, set by prompt_mode= using the :RETURN of the mode passed to set the current prompt_mode.

thread[R]

The current thread in this context

use_readline[R]

Whether Readline is enabled or not.

A copy of the default IRB.conf[:USE_READLINE]

See use_readline= for more information.

use_readline?[R]

Whether Readline is enabled or not.

A copy of the default IRB.conf[:USE_READLINE]

See use_readline= for more information.

use_tracer[R]

Whether Tracer is used when evaluating statements in this context.

See lib/tracer.rb for more information.

use_tracer?[R]

Whether Tracer is used when evaluating statements in this context.

See lib/tracer.rb for more information.

verbose[RW]

Whether verbose messages are displayed or not.

A copy of the default IRB.conf[:VERBOSE]

workspace[RW]

WorkSpace in the current context

workspace_home[R]

The toplevel workspace, see home_workspace

Public Class Methods

new(irb, workspace = nil, input_method = nil, output_method = nil) click to toggle source

Creates a new IRB context.

The optional input_method argument:

nil

uses stdin or Readline

String

uses a File

other

uses this as InputMethod

# File lib/irb/context.rb, line 25
    def initialize(irb, workspace = nil, input_method = nil, output_method = nil)
      @irb = irb
      if workspace
        @workspace = workspace
      else
        @workspace = WorkSpace.new
      end
      @thread = Thread.current if defined? Thread
#      @irb_level = 0

      # copy of default configuration
      @ap_name = IRB.conf[:AP_NAME]
      @rc = IRB.conf[:RC]
      @load_modules = IRB.conf[:LOAD_MODULES]

      @use_readline = IRB.conf[:USE_READLINE]
      @verbose = IRB.conf[:VERBOSE]
      @io = nil

      self.inspect_mode = IRB.conf[:INSPECT_MODE]
      self.math_mode = IRB.conf[:MATH_MODE] if IRB.conf[:MATH_MODE]
      self.use_tracer = IRB.conf[:USE_TRACER] if IRB.conf[:USE_TRACER]
      self.use_loader = IRB.conf[:USE_LOADER] if IRB.conf[:USE_LOADER]
      self.eval_history = IRB.conf[:EVAL_HISTORY] if IRB.conf[:EVAL_HISTORY]

      @ignore_sigint = IRB.conf[:IGNORE_SIGINT]
      @ignore_eof = IRB.conf[:IGNORE_EOF]

      @back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT]

      self.prompt_mode = IRB.conf[:PROMPT_MODE]

      if IRB.conf[:SINGLE_IRB] or !defined?(IRB::JobManager)
        @irb_name = IRB.conf[:IRB_NAME]
      else
        @irb_name = IRB.conf[:IRB_NAME]+"#"+IRB.JobManager.n_jobs.to_s
      end
      @irb_path = "(" + @irb_name + ")"

      case input_method
      when nil
        case use_readline?
        when nil
          if (defined?(ReadlineInputMethod) && STDIN.tty? &&
              IRB.conf[:PROMPT_MODE] != :INF_RUBY)
            @io = ReadlineInputMethod.new
          else
            @io = StdioInputMethod.new
          end
        when false
          @io = StdioInputMethod.new
        when true
          if defined?(ReadlineInputMethod)
            @io = ReadlineInputMethod.new
          else
            @io = StdioInputMethod.new
          end
        end

      when String
        @io = FileInputMethod.new(input_method)
        @irb_name = File.basename(input_method)
        @irb_path = input_method
      else
        @io = input_method
      end
      self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY]

      if output_method
        @output_method = output_method
      else
        @output_method = StdioOutputMethod.new
      end

      @echo = IRB.conf[:ECHO]
      if @echo.nil?
        @echo = true
      end
      self.debug_level = IRB.conf[:DEBUG_LEVEL]
    end

Public Instance Methods

__exit__(ret = 0) click to toggle source
Alias for: exit
_set_last_value(value) click to toggle source

See set_last_value

Alias for: set_last_value
change_workspace(*_main) click to toggle source

Changes the current workspace to given object or binding.

If the optional argument is omitted, the workspace will be home_workspace which is inherited from TOPLEVEL_BINDING or the main object, IRB.conf[:MAIN_CONTEXT] when irb was initialized.

See IRB::WorkSpace.new for more information.

# File lib/irb/ext/change-ws.rb, line 31
def change_workspace(*_main)
  if _main.empty?
    @workspace = home_workspace
    return main
  end

  @workspace = WorkSpace.new(_main[0])

  if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
    main.extend ExtendCommandBundle
  end
end
debug?() click to toggle source

Whether or not debug mode is enabled, see debug_level=.

# File lib/irb/context.rb, line 374
def debug?
  @debug_level > 0
end
debug_level=(value) click to toggle source

Sets the debug level of irb

Can also be set using the --irb_debug command line option.

See Command line options at IRB for more command line options.

# File lib/irb/context.rb, line 368
def debug_level=(value)
  @debug_level = value
  RubyLex.debug_level = value
end
eval_history=(no) click to toggle source

Sets command result history limit.

no is an Integer or nil.

Returns no of history items if greater than 0.

If no is 0, the number of history items is unlimited.

If no is nil, execution result history isn't used (default).

# File lib/irb/ext/history.rb, line 44
def eval_history=(no)
  if no
    if defined?(@eval_history) && @eval_history
      @eval_history_values.size(no)
    else
      @eval_history_values = History.new(no)
      IRB.conf[:__TMP__EHV__] = @eval_history_values
      @workspace.evaluate(self, "__ = IRB.conf[:__TMP__EHV__]")
      IRB.conf.delete(:__TMP_EHV__)
    end
  else
    @eval_history_values = nil
  end
  @eval_history = no
end
exit(ret = 0) click to toggle source

Exits the current session, see IRB.irb_exit

# File lib/irb/context.rb, line 391
def exit(ret = 0)
  IRB.irb_exit(@irb, ret)
end
Also aliased as: __exit__
file_input?() click to toggle source

Whether io uses a File for the input_method passed when creating the current context, see ::new

# File lib/irb/context.rb, line 292
def file_input?
  @io.class == FileInputMethod
end
history_file() click to toggle source

A copy of the default IRB.conf[:HISTORY_FILE]

# File lib/irb/ext/save-history.rb, line 49
def history_file
  IRB.conf[:HISTORY_FILE]
end
history_file=(hist) click to toggle source

Set IRB.conf[:HISTORY_FILE] to the given hist.

# File lib/irb/ext/save-history.rb, line 54
def history_file=(hist)
  IRB.conf[:HISTORY_FILE] = hist
end
home_workspace() click to toggle source

Inherited from TOPLEVEL_BINDING.

# File lib/irb/ext/change-ws.rb, line 16
def home_workspace
  if defined? @home_workspace
    @home_workspace
  else
    @home_workspace = @workspace
  end
end
inspect?() click to toggle source

Whether inspect_mode is set or not, see inspect_mode= for more detail.

# File lib/irb/context.rb, line 286
def inspect?
  @inspect_mode.nil? or @inspect_mode
end
inspect_mode=(opt) click to toggle source

Specifies the inspect mode with opt:

true

display inspect

false

display to_s

nil

inspect mode in non-math mode, non-inspect mode in math mode

See IRB::Inspector for more information.

Can also be set using the --inspect and --noinspect command line options.

See Command line options at IRB for more command line options.

# File lib/irb/context.rb, line 309
def inspect_mode=(opt)

  if i = Inspector::INSPECTORS[opt]
    @inspect_mode = opt
    @inspect_method = i
    i.init
  else
    case opt
    when nil
      if Inspector.keys_with_inspector(Inspector::INSPECTORS[true]).include?(@inspect_mode)
        self.inspect_mode = false
      elsif Inspector.keys_with_inspector(Inspector::INSPECTORS[false]).include?(@inspect_mode)
        self.inspect_mode = true
      else
        puts "Can't switch inspect mode."
        return
      end
    when /^\s*\{.*\}\s*$/
      begin
        inspector = eval "proc#{opt}"
      rescue Exception
        puts "Can't switch inspect mode(#{opt})."
        return
      end
      self.inspect_mode = inspector
    when Proc
      self.inspect_mode = IRB::Inspector(opt)
    when Inspector
      prefix = "usr%d"
      i = 1
      while Inspector::INSPECTORS[format(prefix, i)]; i += 1; end
      @inspect_mode = format(prefix, i)
      @inspect_method = opt
      Inspector.def_inspector(format(prefix, i), @inspect_method)
    else
      puts "Can't switch inspect mode(#{opt})."
      return
    end
  end
  print "Switch to#{unless @inspect_mode; ' non';end} inspect mode.\n" if verbose?
  @inspect_mode
end
irb_level() click to toggle source

Size of the current WorkSpace stack

# File lib/irb/ext/workspaces.rb, line 16
def irb_level
  workspace_stack.size
end
main() click to toggle source

The top-level workspace, see IRB::WorkSpace#main

# File lib/irb/context.rb, line 107
def main
  @workspace.main
end
math_mode=(opt) click to toggle source

Sets bc mode, which loads lib/mathn.rb so fractions or matrix are available.

Also available as the -m command line option.

See Command line options at IRB and the unix manpage bc(1) for more information.

# File lib/irb/ext/math-mode.rb, line 29
def math_mode=(opt)
  if @math_mode == true && !opt
    IRB.fail CantReturnToNormalMode
    return
  end

  @math_mode = opt
  if math_mode
    main.extend Math
    print "start math mode\n" if verbose?
  end
end
pop_workspace() click to toggle source

Removes the last element from the current workspaces stack and returns it, or nil if the current workspace stack is empty.

Also, see push_workspace.

# File lib/irb/ext/workspaces.rb, line 57
def pop_workspace
  if workspaces.empty?
    print "workspace stack empty\n"
    return
  end
  @workspace = workspaces.pop
end
prompt_mode=(mode) click to toggle source

Sets the mode of the prompt in this context.

See Customizing the IRB Prompt at IRB for more information.

# File lib/irb/context.rb, line 270
def prompt_mode=(mode)
  @prompt_mode = mode
  pconf = IRB.conf[:PROMPT][mode]
  @prompt_i = pconf[:PROMPT_I]
  @prompt_s = pconf[:PROMPT_S]
  @prompt_c = pconf[:PROMPT_C]
  @prompt_n = pconf[:PROMPT_N]
  @return_format = pconf[:RETURN]
  if ai = pconf.include?(:AUTO_INDENT)
    @auto_indent_mode = ai
  else
    @auto_indent_mode = IRB.conf[:AUTO_INDENT]
  end
end
prompting?() click to toggle source

Whether verbose? is true, and input_method is either StdioInputMethod or ReadlineInputMethod, see io for more information.

# File lib/irb/context.rb, line 252
def prompting?
  verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) ||
            (defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))
end
push_workspace(*_main) click to toggle source

Creates a new workspace with the given object or binding, and appends it onto the current workspaces stack.

See #change_workspace and IRB::WorkSpace.new for more information.

# File lib/irb/ext/workspaces.rb, line 34
def push_workspace(*_main)
  if _main.empty?
    if workspaces.empty?
      print "No other workspace\n"
      return nil
    end
    ws = workspaces.pop
    workspaces.push @workspace
    @workspace = ws
    return workspaces
  end

  workspaces.push @workspace
  @workspace = WorkSpace.new(@workspace.binding, _main[0])
  if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
    main.extend ExtendCommandBundle
  end
end
save_history() click to toggle source

A copy of the default IRB.conf[:SAVE_HISTORY]

# File lib/irb/ext/save-history.rb, line 26
def save_history
  IRB.conf[:SAVE_HISTORY]
end
save_history=(val) click to toggle source

Sets IRB.conf[:SAVE_HISTORY] to the given val and calls init_save_history with this context.

Will store the number of val entries of history in the history_file

Add the following to your .irbrc to change the number of history entries stored to 1000:

IRB.conf[:SAVE_HISTORY] = 1000
# File lib/irb/ext/save-history.rb, line 39
def save_history=(val)
  IRB.conf[:SAVE_HISTORY] = val
  if val
    main_context = IRB.conf[:MAIN_CONTEXT]
    main_context = self unless main_context
    main_context.init_save_history
  end
end
set_last_value(value) click to toggle source

Sets the return value from the last statement evaluated in this context to last_value.

# File lib/irb/context.rb, line 262
def set_last_value(value)
  @last_value = value
  @workspace.evaluate self, "_ = IRB.CurrentContext.last_value"
end
Also aliased as: _set_last_value
use_loader() click to toggle source

Returns whether irb's own file reader method is used by load/require or not.

This mode is globally affected (irb-wide).

# File lib/irb/ext/use-loader.rb, line 40
def use_loader
  IRB.conf[:USE_LOADER]
end
Also aliased as: use_loader?
use_loader=(opt) click to toggle source

Sets IRB.conf

See use_loader for more information.

# File lib/irb/ext/use-loader.rb, line 49
def use_loader=(opt)

  if IRB.conf[:USE_LOADER] != opt
    IRB.conf[:USE_LOADER] = opt
    if opt
      if !$".include?("irb/cmd/load")
      end
      (class<<@workspace.main;self;end).instance_eval {
        alias_method :load, :irb_load
        alias_method :require, :irb_require
      }
    else
      (class<<@workspace.main;self;end).instance_eval {
        alias_method :load, :__original__load__IRB_use_loader__
        alias_method :require, :__original__require__IRB_use_loader__
      }
    end
  end
  print "Switch to load/require#{unless use_loader; ' non';end} trace mode.\n" if verbose?
  opt
end
use_loader?() click to toggle source
Alias for: use_loader
use_readline=(opt) click to toggle source

Obsolete method.

Can be set using the --noreadline and --readline command line options.

See Command line options at IRB for more command line options.

# File lib/irb/context.rb, line 358
def use_readline=(opt)
  print "This method is obsolete."
  print "Do nothing."
end
use_tracer=(opt) click to toggle source

Sets whether or not to use the Tracer library when evaluating statements in this context.

See lib/tracer.rb for more information.

# File lib/irb/ext/tracer.rb, line 36
def use_tracer=(opt)
  if opt
    Tracer.set_get_line_procs(@irb_path) {
      |line_no, *rests|
      @io.line(line_no)
    }
  elsif !opt && @use_tracer
    Tracer.off
  end
  @use_tracer=opt
end
verbose?() click to toggle source

Returns whether messages are displayed or not.

# File lib/irb/context.rb, line 236
def verbose?
  if @verbose.nil?
    if defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)
      false
    elsif !STDIN.tty? or @io.kind_of?(FileInputMethod)
      true
    else
      false
    end
  else
    @verbose
  end
end
workspaces() click to toggle source

WorkSpaces in the current stack

# File lib/irb/ext/workspaces.rb, line 21
def workspaces
  if defined? @workspaces
    @workspaces
  else
    @workspaces = []
  end
end


module IRB::ContextExtender - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module IRB::ContextExtender

Extends methods for the Context module

In Files

  • lib/irb/extend-command.rb

Public Class Methods

def_extend_command(cmd_name, load_file, *aliases) click to toggle source

Evaluate the given command from the given load_file on the Context module.

Will also define any given aliases for the method.

# File lib/irb/extend-command.rb, line 252
def self.def_extend_command(cmd_name, load_file, *aliases)
  line = __LINE__; Context.module_eval %Q[
    def #{cmd_name}(*opts, &b)
      Context.module_eval {remove_method(:#{cmd_name})}
      require "#{load_file}"
      send :#{cmd_name}, *opts, &b
    end
    for ali in aliases
      alias_method ali, cmd_name
    end
  ], __FILE__, line
end
install_extend_commands() click to toggle source

Installs the default context extensions as irb commands:

IRB::Context#eval_history=

irb/ext/history.rb

IRB::Context#use_tracer=

irb/ext/tracer.rb

IRB::Context#math_mode=

irb/ext/math-mode.rb

IRB::Context#use_loader=

irb/ext/use-loader.rb

IRB::Context#save_history=

irb/ext/save-history.rb

# File lib/irb/extend-command.rb, line 242
def self.install_extend_commands
  for args in @EXTEND_COMMANDS
    def_extend_command(*args)
  end
end


module IRB::ExtendCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module IRB::ExtendCommand

In Files

  • lib/irb/cmd/chws.rb
  • lib/irb/cmd/fork.rb
  • lib/irb/cmd/help.rb
  • lib/irb/cmd/load.rb
  • lib/irb/cmd/nop.rb
  • lib/irb/cmd/pushws.rb
  • lib/irb/cmd/subirb.rb


class IRB::ExtendCommand::ChangeWorkspace - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::ChangeWorkspace

In Files

  • lib/irb/cmd/chws.rb

Parent

Nop


class IRB::ExtendCommand::CurrentWorkingWorkspace - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::CurrentWorkingWorkspace

In Files

  • lib/irb/cmd/chws.rb

Parent

Nop


class IRB::ExtendCommand::Foreground - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::Foreground

In Files

  • lib/irb/cmd/subirb.rb

Parent

IRB::ExtendCommand::Nop


class IRB::ExtendCommand::Fork - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::Fork

In Files

  • lib/irb/cmd/fork.rb

Parent

Nop


class IRB::ExtendCommand::Help - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::Help

In Files

  • lib/irb/cmd/help.rb

Parent

Nop


class IRB::ExtendCommand::IrbCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::IrbCommand

In Files

  • lib/irb/cmd/subirb.rb

Parent

IRB::ExtendCommand::Nop


class IRB::ExtendCommand::Jobs - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::Jobs

In Files

  • lib/irb/cmd/subirb.rb

Parent

IRB::ExtendCommand::Nop


class IRB::ExtendCommand::Kill - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::Kill

In Files

  • lib/irb/cmd/subirb.rb

Parent

IRB::ExtendCommand::Nop


class IRB::ExtendCommand::Load - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::Load

In Files

  • lib/irb/cmd/load.rb

Parent

Nop


class IRB::ExtendCommand::Nop - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::Nop

In Files

  • lib/irb/cmd/nop.rb

Parent

Object


class IRB::ExtendCommand::PopWorkspace - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::PopWorkspace

In Files

  • lib/irb/cmd/pushws.rb

Parent

IRB::ExtendCommand::Workspaces


class IRB::ExtendCommand::PushWorkspace - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::PushWorkspace

In Files

  • lib/irb/cmd/pushws.rb

Parent

IRB::ExtendCommand::Workspaces


class IRB::ExtendCommand::Require - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::Require

In Files

  • lib/irb/cmd/load.rb

Parent

Nop


class IRB::ExtendCommand::Source - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::Source

In Files

  • lib/irb/cmd/load.rb

Parent

Nop


class IRB::ExtendCommand::Workspaces - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ExtendCommand::Workspaces

In Files

  • lib/irb/cmd/pushws.rb

Parent

IRB::ExtendCommand::Nop


module IRB::ExtendCommandBundle - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module IRB::ExtendCommandBundle

Installs the default irb extensions command bundle.

In Files

  • lib/irb/ext/use-loader.rb
  • lib/irb/extend-command.rb

Constants

NO_OVERRIDE

See install_alias_method.

OVERRIDE_ALL

See install_alias_method.

OVERRIDE_PRIVATE_ONLY

See install_alias_method.

Public Class Methods

def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases) click to toggle source

Evaluate the given cmd_name on the given cmd_class Class.

Will also define any given aliases for the method.

The optional load_file parameter will be required within the method definition.

# File lib/irb/extend-command.rb, line 144
def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases)
  case cmd_class
  when Symbol
    cmd_class = cmd_class.id2name
  when String
  when Class
    cmd_class = cmd_class.name
  end

  if load_file
    line = __LINE__; eval %Q[
      def #{cmd_name}(*opts, &b)
        require "#{load_file}"
        arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
        args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
        args << "*opts" if arity < 0
        args << "&block"
        args = args.join(", ")
        line = __LINE__; eval %[
          def #{cmd_name}(\#{args})
            ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
          end
        ], nil, __FILE__, line
        send :#{cmd_name}, *opts, &b
      end
    ], nil, __FILE__, line
  else
    line = __LINE__; eval %Q[
      def #{cmd_name}(*opts, &b)
        ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)
      end
    ], nil, __FILE__, line
  end

  for ali, flag in aliases
    @ALIASES.push [ali, cmd_name, flag]
  end
end
extend_object(obj) click to toggle source

Installs alias methods for the default irb commands on the given object using install_alias_method.

# File lib/irb/extend-command.rb, line 211
def self.extend_object(obj)
  unless (class << obj; ancestors; end).include?(EXCB)
    super
    for ali, com, flg in @ALIASES
      obj.install_alias_method(ali, com, flg)
    end
  end
end
install_extend_commands() click to toggle source

Installs the default irb commands:

irb_current_working_workspace

IRB::Context#main

irb_change_workspace

IRB::Context#change_workspace

irb_workspaces

IRB::Context#workspaces

irb_push_workspace

IRB::Context#push_workspace

irb_pop_workspace

IRB::Context#pop_workspace

irb_load

irb_load

irb_require

irb_require

irb_source

IRB::IrbLoader#source_file

irb

IRB.irb

irb_jobs

JobManager

irb_fg

IRB::JobManager#switch

irb_kill

IRB::JobManager#kill

irb_help

Command line options at IRB

# File lib/irb/extend-command.rb, line 132
def self.install_extend_commands
  for args in @EXTEND_COMMANDS
    def_extend_command(*args)
  end
end

Public Instance Methods

install_alias_method(to, from, override = NO_OVERRIDE) click to toggle source

Installs alias methods for the default irb commands, see ::install_extend_commands.

# File lib/irb/extend-command.rb, line 185
def install_alias_method(to, from, override = NO_OVERRIDE)
  to = to.id2name unless to.kind_of?(String)
  from = from.id2name unless from.kind_of?(String)

  if override == OVERRIDE_ALL or
      (override == OVERRIDE_PRIVATE_ONLY) && !respond_to?(to) or
      (override == NO_OVERRIDE) &&  !respond_to?(to, true)
    target = self
    (class << self; self; end).instance_eval{
      if target.respond_to?(to, true) &&
          !target.respond_to?(EXCB.irb_original_method_name(to), true)
        alias_method(EXCB.irb_original_method_name(to), to)
      end
      alias_method to, from
    }
  else
    print "irb: warn: can't alias #{to} from #{from}.\n"
  end
end
irb_context() click to toggle source

Displays current configuration.

Modifing the configuration is achieved by sending a message to IRB.conf.

# File lib/irb/extend-command.rb, line 35
def irb_context
  IRB.CurrentContext
end
irb_exit(ret = 0) click to toggle source

Quits the current irb context

ret is the optional signal or message to send to IRB::Context#exit

Same as IRB.CurrentContext.exit.

# File lib/irb/extend-command.rb, line 28
def irb_exit(ret = 0)
  irb_context.exit(ret)
end
irb_load(*opts, &b) click to toggle source

Loads the given file similarly to Kernel#load, see IRB::IrbLoader#irb_load

# File lib/irb/ext/use-loader.rb, line 23
def irb_load(*opts, &b)
  ExtendCommand::Load.execute(irb_context, *opts, &b)
end
irb_require(*opts, &b) click to toggle source

Loads the given file similarly to Kernel#require

# File lib/irb/ext/use-loader.rb, line 27
def irb_require(*opts, &b)
  ExtendCommand::Require.execute(irb_context, *opts, &b)
end


class IRB::FileInputMethod - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::FileInputMethod

Use a File for IO with irb, see InputMethod

In Files

  • lib/irb/input-method.rb

Parent

IRB::InputMethod

Attributes

file_name[R]

The file name of this input method, usually given during initialization.

Public Class Methods

new(file) click to toggle source

Creates a new input method object

# File lib/irb/input-method.rb, line 99
def initialize(file)
  super
  @io = IRB::MagicFile.open(file)
end

Public Instance Methods

encoding() click to toggle source

The external encoding for standard input.

# File lib/irb/input-method.rb, line 125
def encoding
  @io.external_encoding
end
eof?() click to toggle source

Whether the end of this input method has been reached, returns true if there is no more data to read.

See IO#eof? for more information.

# File lib/irb/input-method.rb, line 110
def eof?
  @io.eof?
end
gets() click to toggle source

Reads the next line from this input method.

See IO#gets for more information.

# File lib/irb/input-method.rb, line 117
    def gets
      print @prompt
      l = @io.gets
#      print @prompt, l
      l
    end


class IRB::Frame - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::Frame

In Files

  • lib/irb/frame.rb

Parent

Object

Constants

CALL_STACK_OFFSET

Default number of frames offset

INIT_STACK_TIMES

Default number of stack frames

Public Class Methods

bottom(n = 0) click to toggle source

Convenience method for #bottom

# File lib/irb/frame.rb, line 61
def Frame.bottom(n = 0)
  @backtrace.bottom(n)
end
new() click to toggle source

Creates a new stack frame

# File lib/irb/frame.rb, line 26
def initialize
  @frames = [TOPLEVEL_BINDING] * INIT_STACK_TIMES
end
sender() click to toggle source

Returns the binding context of the caller from the last frame initialized

# File lib/irb/frame.rb, line 71
def Frame.sender
  eval "self", @backtrace.top
end
top(n = 0) click to toggle source

Convenience method for #top

# File lib/irb/frame.rb, line 66
def Frame.top(n = 0)
  @backtrace.top(n)
end

Public Instance Methods

bottom(n = 0) click to toggle source

Returns the n number of frames on the call stack from the first frame initialized.

Raises FrameOverflow if there are no frames in the given stack range.

# File lib/irb/frame.rb, line 54
def bottom(n = 0)
  bind = @frames[n]
  Fail FrameOverflow unless bind
  bind
end
top(n = 0) click to toggle source

Returns the n number of frames on the call stack from the last frame initialized.

Raises FrameUnderflow if there are no frames in the given stack range.

# File lib/irb/frame.rb, line 44
def top(n = 0)
  bind = @frames[-(n + CALL_STACK_OFFSET)]
  Fail FrameUnderflow unless bind
  bind
end
trace_func(event, file, line, id, binding) click to toggle source

Used by Kernel#set_trace_func to register each event in the call stack

# File lib/irb/frame.rb, line 31
def trace_func(event, file, line, id, binding)
  case event
  when 'call', 'class'
    @frames.push binding
  when 'return', 'end'
    @frames.pop
  end
end


class IRB::InputMethod - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::InputMethod

In Files

  • lib/irb/input-method.rb

Parent

Object

Attributes

file_name[R]

The file name of this input method, usually given during initialization.

prompt[RW]

The irb prompt associated with this input method

Public Class Methods

new(file = STDIN_FILE_NAME) click to toggle source

Creates a new input method object

# File lib/irb/input-method.rb, line 20
def initialize(file = STDIN_FILE_NAME)
  @file_name = file
end

Public Instance Methods

gets() click to toggle source

Reads the next line from this input method.

See IO#gets for more information.

# File lib/irb/input-method.rb, line 32
def gets
  IRB.fail NotImplementedError, "gets"
end
readable_after_eof?() click to toggle source

Whether this input method is still readable when there is no more data to read.

See IO#eof for more information.

# File lib/irb/input-method.rb, line 41
def readable_after_eof?
  false
end


class IRB::Inspector - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::Inspector

An irb inspector

In order to create your own custom inspector there are two things you should be aware of:

Inspector uses inspect_value, or inspect_proc, for output of return values.

This also allows for an optional init+, or init_proc, which is called when the inspector is activated.

Knowing this, you can create a rudimentary inspector as follows:

irb(main):001:0> ins = IRB::Inspector.new(proc{ |v| "omg! #{v}" })
irb(main):001:0> IRB.CurrentContext.inspect_mode = ins # => omg! #<IRB::Inspector:0x007f46f7ba7d28>
irb(main):001:0> "what?" #=> omg! what?

In Files

  • lib/irb/inspector.rb

Parent

Object

Constants

INSPECTORS

Default inspectors available to irb, this includes:

:pp

Using Kernel#pretty_inspect

:yaml

Using YAML.dump

:marshal

Using Marshal.dump

Public Class Methods

def_inspector(key, arg=nil, &block) click to toggle source

Example

Inspector.def_inspector(key, init_p=nil){|v| v.inspect}
Inspector.def_inspector([key1,..], init_p=nil){|v| v.inspect}
Inspector.def_inspector(key, inspector)
Inspector.def_inspector([key1,...], inspector)

# File lib/irb/inspector.rb, line 63
  def self.def_inspector(key, arg=nil, &block)
#     if !block_given?
#       case arg
#       when nil, Proc
#     inspector = IRB::Inspector(init_p)
#       when Inspector
#     inspector = init_p
#       else
#     IRB.Raise IllegalParameter, init_p
#       end
#       init_p = nil
#     else
#       inspector = IRB::Inspector(block, init_p)
#     end

    if block_given?
      inspector = IRB::Inspector(block, arg)
    else
      inspector = arg
    end

    case key
    when Array
      for k in key
        def_inspector(k, inspector)
      end
    when Symbol
      INSPECTORS[key] = inspector
      INSPECTORS[key.to_s] = inspector
    when String
      INSPECTORS[key] = inspector
      INSPECTORS[key.intern] = inspector
    else
      INSPECTORS[key] = inspector
    end
  end
keys_with_inspector(inspector) click to toggle source

Determines the inspector to use where inspector is one of the keys passed during inspector definition.

# File lib/irb/inspector.rb, line 53
def self.keys_with_inspector(inspector)
  INSPECTORS.select{|k,v| v == inspector}.collect{|k, v| k}
end
new(inspect_proc, init_proc = nil) click to toggle source

Creates a new inspector object, using the given inspect_proc when output return values in irb.

# File lib/irb/inspector.rb, line 102
def initialize(inspect_proc, init_proc = nil)
  @init = init_proc
  @inspect = inspect_proc
end

Public Instance Methods

init() click to toggle source

Proc to call when the inspector is activated, good for requiring dependant libraries.

# File lib/irb/inspector.rb, line 109
def init
  @init.call if @init
end
inspect_value(v) click to toggle source

Proc to call when the input is evaluated and output in irb.

# File lib/irb/inspector.rb, line 114
def inspect_value(v)
  @inspect.call(v)
end


class IRB::Irb - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::Irb

In Files

  • lib/irb/ext/multi-irb.rb
  • lib/irb.rb

Parent

Object

Attributes

context[R]

Returns the current context of this irb session

scanner[RW]

The lexer used by this irb session

Public Class Methods

new(workspace = nil, input_method = nil, output_method = nil) click to toggle source

Creates a new irb session

# File lib/irb.rb, line 428
def initialize(workspace = nil, input_method = nil, output_method = nil)
  @context = Context.new(self, workspace, input_method, output_method)
  @context.main.extend ExtendCommandBundle
  @signal_status = :IN_IRB

  @scanner = RubyLex.new
  @scanner.exception_on_syntax_error = false
end

Public Instance Methods

eval_input() click to toggle source

Evaluates input for this session.

# File lib/irb.rb, line 442
def eval_input
  @scanner.set_prompt do
    |ltype, indent, continue, line_no|
    if ltype
      f = @context.prompt_s
    elsif continue
      f = @context.prompt_c
    elsif indent > 0
      f = @context.prompt_n
    else
      f = @context.prompt_i
    end
    f = "" unless f
    if @context.prompting?
      @context.io.prompt = p = prompt(f, ltype, indent, line_no)
    else
      @context.io.prompt = p = ""
    end
    if @context.auto_indent_mode
      unless ltype
        ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
          indent * 2 - p.size
        ind += 2 if continue
        @context.io.prompt = p + " " * ind if ind > 0
      end
    end
  end

  @scanner.set_input(@context.io) do
    signal_status(:IN_INPUT) do
      if l = @context.io.gets
        print l if @context.verbose?
      else
        if @context.ignore_eof? and @context.io.readable_after_eof?
          l = "\n"
          if @context.verbose?
            printf "Use \"exit\" to leave %s\n", @context.ap_name
          end
        else
          print "\n"
        end
      end
      l
    end
  end

  @scanner.each_top_level_statement do |line, line_no|
    signal_status(:IN_EVAL) do
      begin
        line.untaint
        @context.evaluate(line, line_no)
        output_value if @context.echo?
        exc = nil
      rescue Interrupt => exc
      rescue SystemExit, SignalException
        raise
      rescue Exception => exc
      end
      if exc
        print exc.class, ": ", exc, "\n"
        if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
            !(SyntaxError === exc)
          irb_bug = true
        else
          irb_bug = false
        end

        messages = []
        lasts = []
        levels = 0
        for m in exc.backtrace
          m = @context.workspace.filter_backtrace(m) unless irb_bug
          if m
            if messages.size < @context.back_trace_limit
              messages.push "\tfrom "+m
            else
              lasts.push "\tfrom "+m
              if lasts.size > @context.back_trace_limit
                lasts.shift
                levels += 1
              end
            end
          end
        end
        print messages.join("\n"), "\n"
        unless lasts.empty?
          printf "... %d levels...\n", levels if levels > 0
          print lasts.join("\n")
        end
        print "Maybe IRB bug!\n" if irb_bug
      end
      if $SAFE > 2
        abort "Error: irb does not work for $SAFE level higher than 2"
      end
    end
  end
end
inspect() click to toggle source

Outputs the local variables to this current session, including signal_status and context, using IRB::Locale.

# File lib/irb.rb, line 667
def inspect
  ary = []
  for iv in instance_variables
    case (iv = iv.to_s)
    when "@signal_status"
      ary.push format("%s=:%s", iv, @signal_status.id2name)
    when "@context"
      ary.push format("%s=%s", iv, eval(iv).__to_s__)
    else
      ary.push format("%s=%s", iv, eval(iv))
    end
  end
  format("#<%s: %s>", self.class, ary.join(", "))
end
signal_handle() click to toggle source
# File lib/irb/ext/multi-irb.rb, line 259
def signal_handle
  unless @context.ignore_sigint?
    print "\nabort!!\n" if @context.verbose?
    exit
  end

  case @signal_status
  when :IN_INPUT
    print "^C\n"
    IRB.JobManager.thread(self).raise RubyLex::TerminateLineInput
  when :IN_EVAL
    IRB.irb_abort(self)
  when :IN_LOAD
    IRB.irb_abort(self, LoadAbort)
  when :IN_IRB
    # ignore
  else
    # ignore other cases as well
  end
end
signal_status(status) { || ... } click to toggle source

Evaluates the given block using the given status.

# File lib/irb.rb, line 618
def signal_status(status)
  return yield if @signal_status == :IN_LOAD

  signal_status_back = @signal_status
  @signal_status = status
  begin
    yield
  ensure
    @signal_status = signal_status_back
  end
end
suspend_context(context) { |back_context| ... } click to toggle source

Evaluates the given block using the given context as the Context.

# File lib/irb.rb, line 586
def suspend_context(context)
  @context, back_context = context, @context
  begin
    yield back_context
  ensure
    @context = back_context
  end
end
suspend_input_method(input_method) { |back_io| ... } click to toggle source

Evaluates the given block using the given input_method as the IRB::Context#io.

Used by the irb commands source and irb_load, see IRB Sessions at IRB for more information.

# File lib/irb.rb, line 575
def suspend_input_method(input_method)
  back_io = @context.io
  @context.instance_eval{@io = input_method}
  begin
    yield back_io
  ensure
    @context.instance_eval{@io = back_io}
  end
end
suspend_name(path = nil, name = nil) { |back_path, back_name| ... } click to toggle source

Evaluates the given block using the given path as the IRB::Context#irb_path and name as the IRB::Context#irb_name.

Used by the irb command source, see IRB Sessions at IRB for more information.

# File lib/irb.rb, line 545
def suspend_name(path = nil, name = nil)
  @context.irb_path, back_path = path, @context.irb_path if path
  @context.irb_name, back_name = name, @context.irb_name if name
  begin
    yield back_path, back_name
  ensure
    @context.irb_path = back_path if path
    @context.irb_name = back_name if name
  end
end
suspend_workspace(workspace) { |back_workspace| ... } click to toggle source

Evaluates the given block using the given workspace as the IRB::Context#workspace.

Used by the irb command irb_load, see IRB Sessions at IRB for more information.

# File lib/irb.rb, line 561
def suspend_workspace(workspace)
  @context.workspace, back_workspace = workspace, @context.workspace
  begin
    yield back_workspace
  ensure
    @context.workspace = back_workspace
  end
end


module IRB::IrbLoader - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module IRB::IrbLoader

Provides a few commands for loading files within an irb session.

See ExtendCommandBundle for more information.

In Files

  • lib/irb/ext/loader.rb

Public Instance Methods

irb_load(fn, priv = nil) click to toggle source

Loads the given file similarly to Kernel#load

# File lib/irb/ext/loader.rb, line 27
def irb_load(fn, priv = nil)
  path = search_file_from_ruby_path(fn)
  raise LoadError, "No such file to load -- #{fn}" unless path

  load_file(path, priv)
end
load_file(path, priv = nil) click to toggle source

Loads the given file in the current session's context and evaluates it.

See IRB::Irb#suspend_input_method for more information.

# File lib/irb/ext/loader.rb, line 73
    def load_file(path, priv = nil)
      irb.suspend_name(path, File.basename(path)) do

        if priv
          ws = WorkSpace.new(Module.new)
        else
          ws = WorkSpace.new
        end
        irb.suspend_workspace(ws) do
          irb.suspend_input_method(FileInputMethod.new(path)) do
            |back_io|
            irb.signal_status(:IN_LOAD) do
#             p irb.conf
              if back_io.kind_of?(FileInputMethod)
                irb.eval_input
              else
                begin
                  irb.eval_input
                rescue LoadAbort
                  print "load abort!!\n"
                end
              end
            end
          end
        end
      end
    end
source_file(path) click to toggle source

Loads a given file in the current session and displays the source lines

See IRB::Irb#suspend_input_method for more information.

# File lib/irb/ext/loader.rb, line 51
def source_file(path)
  irb.suspend_name(path, File.basename(path)) do
    irb.suspend_input_method(FileInputMethod.new(path)) do
      |back_io|
      irb.signal_status(:IN_LOAD) do
        if back_io.kind_of?(FileInputMethod)
          irb.eval_input
        else
          begin
            irb.eval_input
          rescue LoadAbort
            print "load abort!!\n"
          end
        end
      end
    end
  end
end


class IRB::JobManager - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::JobManager

In Files

  • lib/irb/ext/multi-irb.rb

Parent

Object

Attributes

current_job[RW]

The active irb session

Public Class Methods

new() click to toggle source

Creates a new JobManager object

# File lib/irb/ext/multi-irb.rb, line 19
def initialize
  # @jobs = [[thread, irb],...]
  @jobs = []
  @current_job = nil
end

Public Instance Methods

delete(key) click to toggle source

Deletes the job at the given key.

# File lib/irb/ext/multi-irb.rb, line 124
def delete(key)
  case key
  when Integer
    IRB.fail NoSuchJob, key unless @jobs[key]
    @jobs[key] = nil
  else
    catch(:EXISTS) do
      @jobs.each_index do
        |i|
        if @jobs[i] and (@jobs[i][0] == key ||
                         @jobs[i][1] == key ||
                         @jobs[i][1].context.main.equal?(key))
          @jobs[i] = nil
          throw :EXISTS
        end
      end
      IRB.fail NoSuchJob, key
    end
  end
  until assoc = @jobs.pop; end unless @jobs.empty?
  @jobs.push assoc
end
insert(irb) click to toggle source

Add the given irb session to the jobs Array.

# File lib/irb/ext/multi-irb.rb, line 59
def insert(irb)
  @jobs.push [Thread.current, irb]
end
inspect() click to toggle source

Outputs a list of jobs, see the irb command irb_jobs, or jobs.

# File lib/irb/ext/multi-irb.rb, line 148
def inspect
  ary = []
  @jobs.each_index do
    |i|
    th, irb = @jobs[i]
    next if th.nil?

    if th.alive?
      if th.stop?
        t_status = "stop"
      else
        t_status = "running"
      end
    else
      t_status = "exited"
    end
    ary.push format("#%d->%s on %s (%s: %s)",
                    i,
                    irb.context.irb_name,
                    irb.context.main,
                    th,
                    t_status)
  end
  ary.join("\n")
end
irb(key) click to toggle source

Returns the irb session for the given key object, see search for more information.

# File lib/irb/ext/multi-irb.rb, line 43
def irb(key)
  _, irb = search(key)
  irb
end
kill(*keys) click to toggle source

Terminates the irb sessions specified by the given keys.

Raises an IrbAlreadyDead exception if one of the given keys is already terminated.

See Thread#exit for more information.

# File lib/irb/ext/multi-irb.rb, line 86
def kill(*keys)
  for key in keys
    th, _ = search(key)
    IRB.fail IrbAlreadyDead unless th.alive?
    th.exit
  end
end
main_irb() click to toggle source

Returns the top level irb session.

# File lib/irb/ext/multi-irb.rb, line 54
def main_irb
  @jobs[0][1]
end
main_thread() click to toggle source

Returns the top level thread.

# File lib/irb/ext/multi-irb.rb, line 49
def main_thread
  @jobs[0][0]
end
n_jobs() click to toggle source

The total number of irb sessions, used to set irb_name of the current Context.

# File lib/irb/ext/multi-irb.rb, line 30
def n_jobs
  @jobs.size
end
search(key) click to toggle source

Returns the associated job for the given key.

If given an Integer, it will return the key index for the jobs Array.

When an instance of Irb is given, it will return the irb session associated with key.

If given an instance of Thread, it will return the associated thread key using Object#=== on the jobs Array.

Otherwise returns the irb session with the same top-level binding as the given key.

Raises a NoSuchJob exception if no job can be found with the given key.

# File lib/irb/ext/multi-irb.rb, line 108
def search(key)
  job = case key
  when Integer
    @jobs[key]
  when Irb
    @jobs.find{|k, v| v.equal?(key)}
  when Thread
    @jobs.assoc(key)
  else
    @jobs.find{|k, v| v.context.main.equal?(key)}
  end
  IRB.fail NoSuchJob, key if job.nil?
  job
end
switch(key) click to toggle source

Changes the current active irb session to the given key in the jobs Array.

Raises an IrbAlreadyDead exception if the given key is no longer alive.

If the given irb session is already active, an IrbSwitchedToCurrentThread exception is raised.

# File lib/irb/ext/multi-irb.rb, line 70
def switch(key)
  th, irb = search(key)
  IRB.fail IrbAlreadyDead unless th.alive?
  IRB.fail IrbSwitchedToCurrentThread if th == Thread.current
  @current_job = irb
  th.run
  Thread.stop
  @current_job = irb(Thread.current)
end
thread(key) click to toggle source

Returns the thread for the given key object, see search for more information.

# File lib/irb/ext/multi-irb.rb, line 36
def thread(key)
  th, = search(key)
  th
end


class IRB::LoadAbort - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::LoadAbort

Raised in the event of an exception in a file loaded from an Irb session

In Files

  • lib/irb/ext/loader.rb

Parent

Exception


class IRB::Locale - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::Locale

In Files

  • lib/irb/lc/ja/encoding_aliases.rb
  • lib/irb/locale.rb

Parent

Object

Constants

LOCALE_DIR
LOCALE_NAME_RE

Attributes

encoding[R]
lang[R]
modifieer[R]
territory[R]

Public Class Methods

new(locale = nil) click to toggle source
# File lib/irb/locale.rb, line 25
def initialize(locale = nil)
  @lang = @territory = @encoding_name = @modifier = nil
  @locale = locale || ENV["IRB_LANG"] || ENV["LC_MESSAGES"] || ENV["LC_ALL"] || ENV["LANG"] || "C"
  if m = LOCALE_NAME_RE.match(@locale)
    @lang, @territory, @encoding_name, @modifier = m[:language], m[:territory], m[:codeset], m[:modifier]

    if @encoding_name
      begin load 'irb/encoding_aliases.rb'; rescue LoadError; end
      if @encoding = @@legacy_encoding_alias_map[@encoding_name]
        warn "%s is obsolete. use %s" % ["#{@lang}_#{@territory}.#{@encoding_name}", "#{@lang}_#{@territory}.#{@encoding.name}"]
      end
      @encoding = Encoding.find(@encoding_name) rescue nil
    end
  end
  @encoding ||= (Encoding.find('locale') rescue Encoding::ASCII_8BIT)
end

Public Instance Methods

String(mes) click to toggle source
# File lib/irb/locale.rb, line 44
def String(mes)
  mes = super(mes)
  if @encoding
    mes.encode(@encoding, undef: :replace)
  else
    mes
  end
end
find(file , paths = $:) click to toggle source
# File lib/irb/locale.rb, line 116
def find(file , paths = $:)
  dir = File.dirname(file)
  dir = "" if dir == "."
  base = File.basename(file)

  if dir.start_with?('/')
    return each_localized_path(dir, base).find{|full_path| File.readable? full_path}
  else
    return search_file(paths, dir, base)
  end
end
format(*opts) click to toggle source
# File lib/irb/locale.rb, line 53
def format(*opts)
  String(super(*opts))
end
gets(*rs) click to toggle source
# File lib/irb/locale.rb, line 57
def gets(*rs)
  String(super(*rs))
end
load(file, priv=nil) click to toggle source
# File lib/irb/locale.rb, line 107
def load(file, priv=nil)
  found = find(file)
  if found
    return real_load(found, priv)
  else
    raise LoadError, "No such file to load -- #{file}"
  end
end
Also aliased as: toplevel_load
print(*opts) click to toggle source
# File lib/irb/locale.rb, line 65
def print(*opts)
  ary = opts.collect{|opt| String(opt)}
  super(*ary)
end
printf(*opts) click to toggle source
# File lib/irb/locale.rb, line 70
def printf(*opts)
  s = format(*opts)
  print s
end
puts(*opts) click to toggle source
# File lib/irb/locale.rb, line 75
def puts(*opts)
  ary = opts.collect{|opt| String(opt)}
  super(*ary)
end
readline(*rs) click to toggle source
# File lib/irb/locale.rb, line 61
def readline(*rs)
  String(super(*rs))
end
require(file, priv = nil) click to toggle source
# File lib/irb/locale.rb, line 80
def require(file, priv = nil)
  rex = Regexp.new("lc/#{Regexp.quote(file)}\.(so|o|sl|rb)?")
  return false if $".find{|f| f =~ rex}

  case file
  when /\.rb$/
    begin
      load(file, priv)
      $".push file
      return true
    rescue LoadError
    end
  when /\.(so|o|sl)$/
    return super
  end

  begin
    load(f = file + ".rb")
    $".push f  #"
    return true
  rescue LoadError
    return ruby_require(file)
  end
end
toplevel_load(file, priv=nil) click to toggle source
Alias for: load


module IRB::MethodExtender - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module IRB::MethodExtender

A convenience module for extending Ruby methods.

In Files

  • lib/irb/extend-command.rb

Public Instance Methods

def_post_proc(base_method, extend_method) click to toggle source

Extends the given base_method with a postfix call to the given extend_method.

# File lib/irb/extend-command.rb, line 288
def def_post_proc(base_method, extend_method)
  base_method = base_method.to_s
  extend_method = extend_method.to_s

  alias_name = new_alias_name(base_method)
  module_eval %Q[
    alias_method alias_name, base_method
    def #{base_method}(*opts)
      send :#{alias_name}, *opts
      send :#{extend_method}, *opts
    end
  ]
end
def_pre_proc(base_method, extend_method) click to toggle source

Extends the given base_method with a prefix call to the given extend_method.

# File lib/irb/extend-command.rb, line 272
def def_pre_proc(base_method, extend_method)
  base_method = base_method.to_s
  extend_method = extend_method.to_s

  alias_name = new_alias_name(base_method)
  module_eval %Q[
    alias_method alias_name, base_method
    def #{base_method}(*opts)
      send :#{extend_method}, *opts
      send :#{alias_name}, *opts
    end
  ]
end
new_alias_name(name, prefix = "__alias_of__", postfix = "__") click to toggle source

Returns a unique method name to use as an alias for the given name.

Usually returns #{prefix}#{name}#{postfix}<num>, example:

new_alias_name('foo') #=> __alias_of__foo__
def bar; end
new_alias_name('bar') #=> __alias_of__bar__2

# File lib/irb/extend-command.rb, line 309
def new_alias_name(name, prefix = "__alias_of__", postfix = "__")
  base_name = "#{prefix}#{name}#{postfix}"
  all_methods = instance_methods(true) + private_instance_methods(true)
  same_methods = all_methods.grep(/^#{Regexp.quote(base_name)}[0-9]*$/)
  return base_name if same_methods.empty?
  no = same_methods.size
  while !same_methods.include?(alias_name = base_name + no)
    no += 1
  end
  alias_name
end


module IRB::Notifier - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module IRB::Notifier

An output formatter used internally by the lexer.

In Files

  • lib/irb/notifier.rb

Public Class Methods

def_notifier(prefix = "", output_method = StdioOutputMethod.new) click to toggle source

Define a new Notifier output source, returning a new CompositeNotifier with the given prefix and output_method.

The optional prefix will be appended to all objects being inspected during output, using the given output_method as the output source. If no output_method is given, StdioOuputMethod will be used, and all expressions will be sent directly to STDOUT without any additional formatting.

# File lib/irb/notifier.rb, line 32
def def_notifier(prefix = "", output_method = StdioOutputMethod.new)
  CompositeNotifier.new(prefix, output_method)
end


class IRB::Notifier::AbstractNotifier - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::Notifier::AbstractNotifier

An abstract class, or superclass, for CompositeNotifier and LeveledNotifier to inherit. It provides several wrapper methods for the OutputMethod object used by the Notifier.

In Files

  • lib/irb/notifier.rb

Parent

Object

Attributes

prefix[R]

The prefix for this Notifier, which is appended to all objects being inspected during output.

Public Class Methods

new(prefix, base_notifier) click to toggle source

Creates a new Notifier object

# File lib/irb/notifier.rb, line 42
def initialize(prefix, base_notifier)
  @prefix = prefix
  @base_notifier = base_notifier
end

Public Instance Methods

exec_if() { |base_notifier| ... } click to toggle source

Execute the given block if notifications are enabled.

# File lib/irb/notifier.rb, line 100
def exec_if
  yield(@base_notifier) if notify?
end
notify?() click to toggle source

A wrapper method used to determine whether notifications are enabled.

Defaults to true.

# File lib/irb/notifier.rb, line 54
def notify?
  true
end
pp(*objs) click to toggle source

Same as ppx, except it uses the prefix given during object initialization. See IRB::OutputMethod#ppx for more detail.

# File lib/irb/notifier.rb, line 83
def pp(*objs)
  if notify?
    @base_notifier.ppx @prefix, *objs
  end
end
ppx(prefix, *objs) click to toggle source

Same as pp, except it concatenates the given prefix with the prefix given during object initialization.

See IRB::OutputMethod#ppx for more detail.

# File lib/irb/notifier.rb, line 93
def ppx(prefix, *objs)
  if notify?
    @base_notifier.ppx @prefix+prefix, *objs
  end
end
print(*opts) click to toggle source

See IRB::OutputMethod#print for more detail.

# File lib/irb/notifier.rb, line 59
def print(*opts)
  @base_notifier.print prefix, *opts if notify?
end
printf(format, *opts) click to toggle source

See IRB::OutputMethod#printf for more detail.

# File lib/irb/notifier.rb, line 69
def printf(format, *opts)
  @base_notifier.printf(prefix + format, *opts) if notify?
end
printn(*opts) click to toggle source

See IRB::OutputMethod#printn for more detail.

# File lib/irb/notifier.rb, line 64
def printn(*opts)
  @base_notifier.printn prefix, *opts if notify?
end
puts(*objs) click to toggle source

See IRB::OutputMethod#puts for more detail.

# File lib/irb/notifier.rb, line 74
def puts(*objs)
  if notify?
    @base_notifier.puts(*objs.collect{|obj| prefix + obj.to_s})
  end
end


class IRB::Notifier::CompositeNotifier - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::Notifier::CompositeNotifier

A class that can be used to create a group of notifier objects with the intent of representing a leveled notification system for irb.

This class will allow you to generate other notifiers, and assign them the appropriate level for output.

The Notifier class provides a class-method IRB::Notifier.def_notifier to create a new composite notifier. Using the first composite notifier object you create, sibling notifiers can be initialized with def_notifier.

In Files

  • lib/irb/notifier.rb

Parent

IRB::Notifier::AbstractNotifier

Attributes

level[R]

Returns the leveled notifier for this object

level_notifier[R]

Returns the leveled notifier for this object

notifiers[R]

List of notifiers in the group

Public Class Methods

new(prefix, base_notifier) click to toggle source

Create a new composite notifier object with the given prefix, and base_notifier to use for output.

# File lib/irb/notifier.rb, line 118
def initialize(prefix, base_notifier)
  super

  @notifiers = [D_NOMSG]
  @level_notifier = D_NOMSG
end

Public Instance Methods

def_notifier(level, prefix = "") click to toggle source

Creates a new LeveledNotifier in the composite notifiers group.

The given prefix will be assigned to the notifier, and level will be used as the index of the notifiers Array.

This method returns the newly created instance.

# File lib/irb/notifier.rb, line 134
def def_notifier(level, prefix = "")
  notifier = LeveledNotifier.new(self, level, prefix)
  @notifiers[level] = notifier
  notifier
end
level=(value) click to toggle source
Alias for: level_notifier=
level_notifier=(value) click to toggle source

Sets the leveled notifier for this object.

When the given value is an instance of AbstractNotifier, level_notifier is set to the given object.

When an Integer is given, level_notifier is set to the notifier at the index value in the notifiers Array.

If no notifier exists at the index value in the notifiers Array, an ErrUndefinedNotifier exception is raised.

An ErrUnrecognizedLevel exception is raised if the given value is not found in the existing notifiers Array, or an instance of AbstractNotifier

# File lib/irb/notifier.rb, line 158
def level_notifier=(value)
  case value
  when AbstractNotifier
    @level_notifier = value
  when Integer
    l = @notifiers[value]
    Notifier.Raise ErrUndefinedNotifer, value unless l
    @level_notifier = l
  else
    Notifier.Raise ErrUnrecognizedLevel, value unless l
  end
end
Also aliased as: level=


class IRB::Notifier::LeveledNotifier - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::Notifier::LeveledNotifier

A leveled notifier is comparable to the composite group from IRB::Notifier::CompositeNotifier#notifiers.

In Files

  • lib/irb/notifier.rb

Parent

IRB::Notifier::AbstractNotifier

Included Modules

  • Comparable

Attributes

level[R]

The current level of this notifier object

Public Class Methods

new(base, level, prefix) click to toggle source

Create a new leveled notifier with the given base, and prefix to send to IRB::Notifier::AbstractNotifier.new

The given level is used to compare other leveled notifiers in the CompositeNotifier group to determine whether or not to output notifications.

# File lib/irb/notifier.rb, line 185
def initialize(base, level, prefix)
  super(prefix, base)

  @level = level
end

Public Instance Methods

<=>(other) click to toggle source

Compares the level of this notifier object with the given other notifier.

See the Comparable module for more information.

# File lib/irb/notifier.rb, line 198
def <=>(other)
  @level <=> other.level
end
notify?() click to toggle source

Whether to output messages to the output method, depending on the level of this notifier object.

# File lib/irb/notifier.rb, line 204
def notify?
  @base_notifier.level >= self
end


class IRB::Notifier::NoMsgNotifier - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::Notifier::NoMsgNotifier

NoMsgNotifier is a LeveledNotifier that's used as the default notifier when creating a new CompositeNotifier.

This notifier is used as the zero index, or level 0, for IRB::Notifier::CompositeNotifier#notifiers, and will not output messages of any sort.

In Files

  • lib/irb/notifier.rb

Parent

IRB::Notifier::LeveledNotifier

Public Class Methods

new() click to toggle source

Creates a new notifier that should not be used to output messages.

# File lib/irb/notifier.rb, line 216
def initialize
  @base_notifier = nil
  @level = 0
  @prefix = ""
end

Public Instance Methods

notify?() click to toggle source

Ensures notifications are ignored, see IRB::Notifier::AbstractNotifier#notify? for more information.

# File lib/irb/notifier.rb, line 224
def notify?
  false
end


class IRB::OutputMethod - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::OutputMethod

An abstract output class for IO in irb. This is mainly used internally by IRB::Notifier. You can define your own output method to use with IRB::Irb.new, or IRB::Context.new

In Files

  • lib/irb/output-method.rb

Parent

Object

Public Instance Methods

parse_printf_format(format, opts) click to toggle source

Returns an array of the given format and opts to be used by Kernel#sprintf, if there was a successful Regexp match in the given format from printf

%
<flag>  [#0- +]
<minimum field width> (\*|\*[1-9][0-9]*\$|[1-9][0-9]*)
<precision>.(\*|\*[1-9][0-9]*\$|[1-9][0-9]*|)?
#<length modifier>(hh|h|l|ll|L|q|j|z|t)
<conversion specifier>[diouxXeEfgGcsb%]
# File lib/irb/output-method.rb, line 53
def parse_printf_format(format, opts)
  return format, opts if $1.size % 2 == 1
end
pp(*objs) click to toggle source

Prints the given objs calling Object#inspect on each.

See puts for more detail.

# File lib/irb/output-method.rb, line 69
def pp(*objs)
  puts(*objs.collect{|obj| obj.inspect})
end
ppx(prefix, *objs) click to toggle source

Prints the given objs calling Object#inspect on each and appending the given prefix.

See puts for more detail.

# File lib/irb/output-method.rb, line 77
def ppx(prefix, *objs)
  puts(*objs.collect{|obj| prefix+obj.inspect})
end
print(*opts) click to toggle source

Open this method to implement your own output method, raises a NotImplementedError if you don't define print in your own class.

# File lib/irb/output-method.rb, line 25
def print(*opts)
  OutputMethod.Raise NotImplementedError, "print"
end
printf(format, *opts) click to toggle source

Extends IO#printf to format the given opts for Kernel#sprintf using parse_printf_format

# File lib/irb/output-method.rb, line 36
def printf(format, *opts)
  if /(%*)%I/ =~ format
    format, opts = parse_printf_format(format, opts)
  end
  print sprintf(format, *opts)
end
printn(*opts) click to toggle source

Prints the given opts, with a newline delimiter.

# File lib/irb/output-method.rb, line 30
def printn(*opts)
  print opts.join(" "), "\n"
end
puts(*objs) click to toggle source

Calls print on each element in the given objs, followed by a newline character.

# File lib/irb/output-method.rb, line 59
def puts(*objs)
  for obj in objs
    print(*obj)
    print "\n"
  end
end


class IRB::ReadlineInputMethod - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::ReadlineInputMethod

In Files

  • lib/irb/input-method.rb

Parent

IRB::InputMethod

Included Modules

  • Readline

Public Class Methods

new() click to toggle source

Creates a new input method object using Readline

# File lib/irb/input-method.rb, line 135
def initialize
  super

  @line_no = 0
  @line = []
  @eof = false

  @stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
  @stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
end

Public Instance Methods

encoding() click to toggle source

The external encoding for standard input.

# File lib/irb/input-method.rb, line 187
def encoding
  @stdin.external_encoding
end
eof?() click to toggle source

Whether the end of this input method has been reached, returns true if there is no more data to read.

See IO#eof? for more information.

# File lib/irb/input-method.rb, line 165
def eof?
  @eof
end
gets() click to toggle source

Reads the next line from this input method.

See IO#gets for more information.

# File lib/irb/input-method.rb, line 149
def gets
  Readline.input = @stdin
  Readline.output = @stdout
  if l = readline(@prompt, false)
    HISTORY.push(l) if !l.empty?
    @line[@line_no += 1] = l + "\n"
  else
    @eof = true
    l
  end
end
line(line_no) click to toggle source

Returns the current line number for io.

line counts the number of times gets is called.

See IO#lineno for more information.

# File lib/irb/input-method.rb, line 182
def line(line_no)
  @line[line_no]
end
readable_after_eof?() click to toggle source

Whether this input method is still readable when there is no more data to read.

See IO#eof for more information.

# File lib/irb/input-method.rb, line 173
def readable_after_eof?
  true
end


class IRB::SLex - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::SLex

In Files

  • lib/irb/slex.rb

Parent

Object


class IRB::SLex::Node - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::SLex::Node

In Files

  • lib/irb/slex.rb

Parent

Object


class IRB::StdioInputMethod - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::StdioInputMethod

In Files

  • lib/irb/input-method.rb

Parent

IRB::InputMethod

Public Class Methods

new() click to toggle source

Creates a new input method object

# File lib/irb/input-method.rb, line 48
def initialize
  super
  @line_no = 0
  @line = []
  @stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
  @stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
end

Public Instance Methods

encoding() click to toggle source

The external encoding for standard input.

# File lib/irb/input-method.rb, line 91
def encoding
  @stdin.external_encoding
end
eof?() click to toggle source

Whether the end of this input method has been reached, returns true if there is no more data to read.

See IO#eof? for more information.

# File lib/irb/input-method.rb, line 69
def eof?
  @stdin.eof?
end
gets() click to toggle source

Reads the next line from this input method.

See IO#gets for more information.

# File lib/irb/input-method.rb, line 59
def gets
  print @prompt
  line = @stdin.gets
  @line[@line_no += 1] = line
end
line(line_no) click to toggle source

Returns the current line number for io.

line counts the number of times gets is called.

See IO#lineno for more information.

# File lib/irb/input-method.rb, line 86
def line(line_no)
  @line[line_no]
end
readable_after_eof?() click to toggle source

Whether this input method is still readable when there is no more data to read.

See IO#eof for more information.

# File lib/irb/input-method.rb, line 77
def readable_after_eof?
  true
end


class IRB::StdioOutputMethod - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::StdioOutputMethod

A standard output printer

In Files

  • lib/irb/output-method.rb

Parent

IRB::OutputMethod

Public Instance Methods

print(*opts) click to toggle source

Prints the given opts to standard output, see IO#print for more information.

# File lib/irb/output-method.rb, line 87
def print(*opts)
  STDOUT.print(*opts)
end


class IRB::WorkSpace - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class IRB::WorkSpace

In Files

  • lib/irb/ext/tracer.rb
  • lib/irb/workspace.rb

Parent

Object

Attributes

binding[R]

The Binding of this workspace

main[R]

The top-level workspace of this context, also available as IRB.conf[:__MAIN__]

Public Class Methods

new(*main) click to toggle source

Creates a new workspace.

set self to main if specified, otherwise inherit main from TOPLEVEL_BINDING.

# File lib/irb/workspace.rb, line 17
    def initialize(*main)
      if main[0].kind_of?(Binding)
        @binding = main.shift
      elsif IRB.conf[:SINGLE_IRB]
        @binding = TOPLEVEL_BINDING
      else
        case IRB.conf[:CONTEXT_MODE]
        when 0 # binding in proc on TOPLEVEL_BINDING
          @binding = eval("proc{binding}.call",
                      TOPLEVEL_BINDING,
                      __FILE__,
                      __LINE__)
        when 1 # binding in loaded file
          require "tempfile"
          f = Tempfile.open("irb-binding")
          f.print <<EOF
          $binding = binding
EOF
          f.close
          load f.path
          @binding = $binding

        when 2 # binding in loaded file(thread use)
          unless defined? BINDING_QUEUE
            require "thread"

            IRB.const_set(:BINDING_QUEUE, SizedQueue.new(1))
            Thread.abort_on_exception = true
            Thread.start do
              eval "require \"irb/ws-for-case-2\"", TOPLEVEL_BINDING, __FILE__, __LINE__
            end
            Thread.pass
          end
          @binding = BINDING_QUEUE.pop

        when 3 # binging in function on TOPLEVEL_BINDING(default)
          @binding = eval("def irb_binding; private; binding; end; irb_binding",
                      TOPLEVEL_BINDING,
                      __FILE__,
                      __LINE__ - 3)
        end
      end
      if main.empty?
        @main = eval("self", @binding)
      else
        @main = main[0]
        IRB.conf[:__MAIN__] = @main
        case @main
        when Module
          @binding = eval("IRB.conf[:__MAIN__].module_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
        else
          begin
            @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
          rescue TypeError
            IRB.fail CantChangeBinding, @main.inspect
          end
        end
      end
      eval("_=nil", @binding)
    end

Public Instance Methods

__evaluate__(context, statements, file = nil, line = nil) click to toggle source
Alias for: evaluate
evaluate(context, statements, file = nil, line = nil) click to toggle source

Evaluate the context of this workspace and use the Tracer library to output the exact lines of code are being executed in chronological order.

See lib/tracer.rb for more information.

# File lib/irb/ext/tracer.rb, line 55
def evaluate(context, statements, file = nil, line = nil)
  if context.use_tracer? && file != nil && line != nil
    Tracer.on
    begin
      __evaluate__(context, statements, file, line)
    ensure
      Tracer.off
    end
  else
    __evaluate__(context, statements, file || __FILE__, line || __LINE__)
  end
end
Also aliased as: __evaluate__
filter_backtrace(bt) click to toggle source

error message manipulator

# File lib/irb/workspace.rb, line 90
def filter_backtrace(bt)
  case IRB.conf[:CONTEXT_MODE]
  when 0
    return nil if bt =~ /\(irb_local_binding\)/
  when 1
    if(bt =~ %r/tmp/irb-binding! or
       bt =~ %rirb/.*\.rb! or
       bt =~ /irb\.rb/)
      return nil
    end
  when 2
    return nil if bt =~ /irb\/.*\.rb/
    return nil if bt =~ /irb\.rb/
  when 3
    return nil if bt =~ /irb\/.*\.rb/
    return nil if bt =~ /irb\.rb/
    bt = bt.sub(/:\s*in `irb_binding'/, '')
  end
  bt
end


class Integer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Integer

Add double dispatch to Integer

In Files

  • lib/prime.rb
  • ext/bigdecimal/lib/bigdecimal/util.rb
  • ext/openssl/lib/openssl/bn.rb

Parent

Numeric

Public Class Methods

each_prime(ubound) { |prime| ... } click to toggle source

Iterates the given block over all prime numbers.

See Primeeach for more details.

# File lib/prime.rb, line 40
def Integer.each_prime(ubound, &block) # :yields: prime
  Prime.each(ubound, &block)
end
from_prime_division(pd) click to toggle source

Re-composes a prime factorization and returns the product.

See Prime#int_from_prime_division for more details.

# File lib/prime.rb, line 21
def Integer.from_prime_division(pd)
  Prime.int_from_prime_division(pd)
end

Public Instance Methods

prime?() click to toggle source

Returns true if self is a prime number, false for a composite.

# File lib/prime.rb, line 33
def prime?
  Prime.prime?(self)
end
prime_division(generator = Prime::Generator23.new) click to toggle source

Returns the factorization of self.

See Prime#prime_division for more details.

# File lib/prime.rb, line 28
def prime_division(generator = Prime::Generator23.new)
  Prime.prime_division(self, generator)
end
to_bn() click to toggle source
# File ext/openssl/lib/openssl/bn.rb, line 31
def to_bn
  OpenSSL::BN::new(self.to_s(16), 16)
end
to_d → bigdecimal click to toggle source

Convert int to a BigDecimal and return it.

require 'bigdecimal'
require 'bigdecimal/util'

42.to_d
# => #<BigDecimal:1008ef070,'0.42E2',9(36)>

# File ext/bigdecimal/lib/bigdecimal/util.rb, line 13
def to_d
  BigDecimal(self)
end


module JSON - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module JSON

JavaScript Object Notation (JSON)

JSON is a lightweight data-interchange format. It is easy for us humans to read and write. Plus, equally simple for machines to generate or parse. JSON is completely language agnostic, making it the ideal interchange format.

Built on two universally available structures:

1. A collection of name/value pairs. Often referred to as an _object_, hash table, record, struct, keyed list, or associative array.
2. An ordered list of values. More commonly called an _array_, vector, sequence or list.

To read more about JSON visit: json.org

Parsing JSON

To parse a JSON string received by another application or generated within your existing application:

require 'json'

my_hash = JSON.parse('{"hello": "goodbye"}')
puts my_hash["hello"] => "goodbye"

Notice the extra quotes '' around the hash notation. Ruby expects the argument to be a string and can't convert objects like a hash or array.

Ruby converts your string into a hash

Generating JSON

Creating a JSON string for communication or serialization is just as simple.

require 'json'

my_hash = {:hello => "goodbye"}
puts JSON.generate(my_hash) => "{\"hello\":\"goodbye\"}"

Or an alternative way:

require 'json'
puts {:hello => "goodbye"}.to_json => "{\"hello\":\"goodbye\"}"

JSON.generate only allows objects or arrays to be converted to JSON syntax. to_json, however, accepts many Ruby classes even though it acts only as a method for serialization:

require 'json'

1.to_json => "1"

In Files

  • ext/json/lib/json/common.rb
  • ext/json/lib/json/ext.rb
  • ext/json/lib/json/generic_object.rb
  • ext/json/lib/json/version.rb
  • ext/json/lib/json.rb

Constants

Infinity
JSON_LOADED
MinusInfinity
NaN
UnparserError

For backwards compatibility

VERSION

JSON version

Attributes

create_id[RW]

This is create identifier, which is used to decide if the json_create hook of a class should be called. It defaults to 'json_class'.

dump_default_options[RW]

The global default options for the #dump method:

:max_nesting: false
:allow_nan: true
:quirks_mode: true
generator[R]

Returns the JSON generator module that is used by JSON. This is either JSON::Ext::Generator or JSON::Pure::Generator.

load_default_options[RW]

The global default options for the #load method:

:max_nesting: false
:allow_nan: true
:quirks_mode: true
parser[R]

Returns the JSON parser class that is used by JSON. This is either JSON::Ext::Parser or JSON::Pure::Parser.

state[RW]

Returns the JSON generator state class that is used by JSON. This is either JSON::Ext::Generator::State or JSON::Pure::Generator::State.

Public Class Methods

[](object, opts = {}) click to toggle source

If object is string-like, parse the string and return the parsed result as a Ruby data structure. Otherwise generate a JSON text from the Ruby data structure object and return it.

The opts argument is passed through to generate/parse respectively. See generate and parse for their documentation.

# File ext/json/lib/json/common.rb, line 12
def [](object, opts = {})
  if object.respond_to? :to_str
    JSON.parse(object.to_str, opts)
  else
    JSON.generate(object, opts)
  end
end
const_defined_in?(modul, constant) click to toggle source
# File ext/json/lib/json/common.rb, line 433
def self.const_defined_in?(modul, constant)
  modul.const_defined?(constant)
end
iconv(to, from, string) click to toggle source

Encodes string using Ruby's String.encode

# File ext/json/lib/json/common.rb, line 421
def self.iconv(to, from, string)
  string.encode(to, from)
end
restore(source, proc = nil, options = {}) click to toggle source
Alias for: load

Public Instance Methods

dump(obj, anIO = nil, limit = nil) click to toggle source

Dumps obj as a JSON string, i.e. calls generate on the object and returns the result.

If anIO (an IO-like object or an object that responds to the write method) was given, the resulting JSON is written to it.

If the number of nested arrays or objects exceeds limit, an ArgumentError exception is raised. This argument is similar (but not exactly the same!) to the limit argument in Marshal.dump.

The default options for the generator can be changed via the ::dump_default_options method.

This method is part of the implementation of the load/dump interface of Marshal and YAML.

# File ext/json/lib/json/common.rb, line 385
def dump(obj, anIO = nil, limit = nil)
  if anIO and limit.nil?
    anIO = anIO.to_io if anIO.respond_to?(:to_io)
    unless anIO.respond_to?(:write)
      limit = anIO
      anIO = nil
    end
  end
  opts = JSON.dump_default_options
  limit and opts.update(:max_nesting => limit)
  result = generate(obj, opts)
  if anIO
    anIO.write result
    anIO
  else
    result
  end
rescue JSON::NestingError
  raise ArgumentError, "exceed depth limit"
end
fast_generate(obj, opts = nil) click to toggle source

Generate a JSON document from the Ruby data structure obj and return it. This method disables the checks for circles in Ruby objects.

WARNING: Be careful not to pass any Ruby data structures with circles as obj argument because this will cause JSON to go into an infinite loop.

# File ext/json/lib/json/common.rb, line 239
def fast_generate(obj, opts = nil)
  if State === opts
    state, opts = opts, nil
  else
    state = FAST_STATE_PROTOTYPE.dup
  end
  if opts
    if opts.respond_to? :to_hash
      opts = opts.to_hash
    elsif opts.respond_to? :to_h
      opts = opts.to_h
    else
      raise TypeError, "can't convert #{opts.class} into Hash"
    end
    state.configure(opts)
  end
  state.generate(obj)
end
generate(obj, opts = nil) click to toggle source

Generate a JSON document from the Ruby data structure obj and return it. state is

  • a JSON::State object,

  • or a Hash like object (responding to to_hash),

  • or an object convertible into a hash by a to_h method,

that is used as or to configure a State object.

It defaults to a state object, that creates the shortest possible JSON text in one line, checks for circular data structures and doesn't allow NaN, Infinity, and -Infinity.

A state hash can have the following keys:

  • indent: a string used to indent levels (default: ''),

  • space: a string that is put after, a : or , delimiter (default: ''),

  • space_before: a string that is put before a : pair delimiter (default: ''),

  • object_nl: a string that is put at the end of a JSON object (default: ''),

  • array_nl: a string that is put at the end of a JSON array (default: ''),

  • allow_nan: true if NaN, Infinity, and -Infinity should be generated, otherwise an exception is thrown if these values are encountered. This options defaults to false.

  • max_nesting: The maximum depth of nesting allowed in the data structures from which JSON is to be generated. Disable depth checking with :max_nesting => false, it defaults to 100.

See also the #fast_generate for the fastest creation method with the least amount of sanity checks, and the #pretty_generate method for some defaults for pretty output.

# File ext/json/lib/json/common.rb, line 208
def generate(obj, opts = nil)
  if State === opts
    state, opts = opts, nil
  else
    state = SAFE_STATE_PROTOTYPE.dup
  end
  if opts
    if opts.respond_to? :to_hash
      opts = opts.to_hash
    elsif opts.respond_to? :to_h
      opts = opts.to_h
    else
      raise TypeError, "can't convert #{opts.class} into Hash"
    end
    state = state.configure(opts)
  end
  state.generate(obj)
end
load(source, proc = nil, options = {}) click to toggle source

Load a ruby data structure from a JSON source and return it. A source can either be a string-like object, an IO-like object, or an object responding to the read method. If proc was given, it will be called with any nested Ruby object as an argument recursively in depth first order. To modify the default options pass in the optional options argument as well.

BEWARE: This method is meant to serialise data from trusted user input, like from your own database server or clients under your control, it could be dangerous to allow untrusted users to pass JSON sources into it. The default options for the parser can be changed via the ::load_default_options method.

This method is part of the implementation of the load/dump interface of Marshal and YAML.

# File ext/json/lib/json/common.rb, line 323
def load(source, proc = nil, options = {})
  opts = load_default_options.merge options
  if source.respond_to? :to_str
    source = source.to_str
  elsif source.respond_to? :to_io
    source = source.to_io.read
  elsif source.respond_to?(:read)
    source = source.read
  end
  if opts[:quirks_mode] && (source.nil? || source.empty?)
    source = 'null'
  end
  result = parse(source, opts)
  recurse_proc(result, &proc) if proc
  result
end
Also aliased as: restore
parse(source, opts = {}) click to toggle source

Parse the JSON document source into a Ruby data structure and return it.

opts can have the following keys:

  • max_nesting: The maximum depth of nesting allowed in the parsed data structures. Disable depth checking with :max_nesting => false. It defaults to 100.

  • allow_nan: If set to true, allow NaN, Infinity and -Infinity in defiance of RFC 4627 to be parsed by the Parser. This option defaults to false.

  • symbolize_names: If set to true, returns symbols for the names (keys) in a JSON object. Otherwise strings are returned. Strings are the default.

  • create_additions: If set to false, the Parser doesn't create additions even if a matching class and ::create_id was found. This option defaults to true.

  • object_class: Defaults to Hash

  • array_class: Defaults to Array

# File ext/json/lib/json/common.rb, line 154
def parse(source, opts = {})
  Parser.new(source, opts).parse
end
parse!(source, opts = {}) click to toggle source

Parse the JSON document source into a Ruby data structure and return it. The bang version of the parse method defaults to the more dangerous values for the opts hash, so be sure only to parse trusted source documents.

opts can have the following keys:

  • max_nesting: The maximum depth of nesting allowed in the parsed data structures. Enable depth checking with :max_nesting => anInteger. The parse! methods defaults to not doing max depth checking: This can be dangerous if someone wants to fill up your stack.

  • allow_nan: If set to true, allow NaN, Infinity, and -Infinity in defiance of RFC 4627 to be parsed by the Parser. This option defaults to true.

  • create_additions: If set to false, the Parser doesn't create additions even if a matching class and ::create_id was found. This option defaults to true.

# File ext/json/lib/json/common.rb, line 173
def parse!(source, opts = {})
  opts = {
    :max_nesting  => false,
    :allow_nan    => true
  }.update(opts)
  Parser.new(source, opts).parse
end
pretty_generate(obj, opts = nil) click to toggle source

Generate a JSON document from the Ruby data structure obj and return it. The returned document is a prettier form of the document returned by unparse.

The opts argument can be used to configure the generator. See the generate method for a more detailed explanation.

# File ext/json/lib/json/common.rb, line 270
def pretty_generate(obj, opts = nil)
  if State === opts
    state, opts = opts, nil
  else
    state = PRETTY_STATE_PROTOTYPE.dup
  end
  if opts
    if opts.respond_to? :to_hash
      opts = opts.to_hash
    elsif opts.respond_to? :to_h
      opts = opts.to_h
    else
      raise TypeError, "can't convert #{opts.class} into Hash"
    end
    state.configure(opts)
  end
  state.generate(obj)
end
recurse_proc(result, &proc) click to toggle source

Recursively calls passed Proc if the parsed data structure is an Array or Hash

# File ext/json/lib/json/common.rb, line 341
def recurse_proc(result, &proc)
  case result
  when Array
    result.each { |x| recurse_proc x, &proc }
    proc.call result
  when Hash
    result.each { |x, y| recurse_proc x, &proc; recurse_proc y, &proc }
    proc.call result
  else
    proc.call result
  end
end


class JSON::CircularDatastructure - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class JSON::CircularDatastructure

In Files

  • ext/json/lib/json/common.rb

Parent

JSON::NestingError


module JSON::Ext - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module JSON::Ext

This module holds all the modules/classes that implement JSON's functionality as C extensions.

In Files

  • ext/json/lib/json/ext.rb


class JSON::UnparserError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class JSON::UnparserError

This exception is raised if a generator or unparser error occurs.

In Files

  • ext/json/lib/json/common.rb

Parent

JSON::JSONError


class JSON::GenericObject - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class JSON::GenericObject

In Files

  • ext/json/lib/json/generic_object.rb

Parent

OpenStruct

Attributes

json_creatable[W]

Public Class Methods

from_hash(object) click to toggle source
# File ext/json/lib/json/generic_object.rb, line 20
def from_hash(object)
  case
  when object.respond_to?(:to_hash)
    result = new
    object.to_hash.each do |key, value|
      result[key] = from_hash(value)
    end
    result
  when object.respond_to?(:to_ary)
    object.to_ary.map { |a| from_hash(a) }
  else
    object
  end
end
json_creatable?() click to toggle source
# File ext/json/lib/json/generic_object.rb, line 8
def json_creatable?
  @json_creatable
end
json_create(data) click to toggle source
# File ext/json/lib/json/generic_object.rb, line 14
def json_create(data)
  data = data.dup
  data.delete JSON.create_id
  self[data]
end

Public Instance Methods

[](name) click to toggle source
# File ext/json/lib/json/generic_object.rb, line 41
def [](name)
  table[name.to_sym]
end
[]=(name, value) click to toggle source
# File ext/json/lib/json/generic_object.rb, line 45
def []=(name, value)
  __send__ "#{name}=", value
end
as_json(*) click to toggle source
# File ext/json/lib/json/generic_object.rb, line 53
def as_json(*)
  { JSON.create_id => self.class.name }.merge to_hash
end
to_hash() click to toggle source
# File ext/json/lib/json/generic_object.rb, line 37
def to_hash
  table
end
to_json(*a) click to toggle source
# File ext/json/lib/json/generic_object.rb, line 57
def to_json(*a)
  as_json.to_json(*a)
end
|(other) click to toggle source
# File ext/json/lib/json/generic_object.rb, line 49
def |(other)
  self.class[other.to_hash.merge(to_hash)]
end


class JSON::JSONError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class JSON::JSONError

The base exception for JSON errors.

In Files

  • ext/json/lib/json/common.rb

Parent

StandardError

Public Class Methods

wrap(exception) click to toggle source
# File ext/json/lib/json/common.rb, line 107
def self.wrap(exception)
  obj = new("Wrapped(#{exception.class}): #{exception.message.inspect}")
  obj.set_backtrace exception.backtrace
  obj
end


class JSON::MissingUnicodeSupport - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class JSON::MissingUnicodeSupport

This exception is raised if the required unicode support is missing on the system. Usually this means that the iconv library is not installed.

In Files

  • ext/json/lib/json/common.rb

Parent

JSON::JSONError


class JSON::NestingError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class JSON::NestingError

This exception is raised if the nesting of parsed data structures is too deep.

In Files

  • ext/json/lib/json/common.rb

Parent

JSON::ParserError


class JSON::ParserError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class JSON::ParserError

This exception is raised if a parser error occurs.

In Files

  • ext/json/lib/json/common.rb

Parent

JSON::JSONError


module Jacobian - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Jacobian

require 'bigdecimal/jacobian'

Provides methods to compute the Jacobian matrix of a set of equations at a point x. In the methods below:

f is an Object which is used to compute the Jacobian matrix of the equations. It must provide the following methods:

f.values(x)

returns the values of all functions at x

f.zero

returns 0.0

f.one

returns 1.0

f.two

returns 2.0

f.ten

returns 10.0

f.eps

returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.

x is the point at which to compute the Jacobian.

fx is f.values(x).

In Files

  • ext/bigdecimal/lib/bigdecimal/jacobian.rb

Public Instance Methods

dfdxi(f,fx,x,i) click to toggle source

Computes the derivative of f at x. fx is the value of f at x.

# File ext/bigdecimal/lib/bigdecimal/jacobian.rb, line 44
def dfdxi(f,fx,x,i)
  nRetry = 0
  n = x.size
  xSave = x[i]
  ok = 0
  ratio = f.ten*f.ten*f.ten
  dx = x[i].abs/ratio
  dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps)
  dx = f.one/f.ten     if isEqual(dx,f.zero,f.zero,f.eps)
  until ok>0 do
    s = f.zero
    deriv = []
    nRetry += 1
    if nRetry > 100
      raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]"
    end
    dx = dx*f.two
    x[i] += dx
    fxNew = f.values(x)
    for j in 0...n do
      if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then
        ok += 1
        deriv <<= (fxNew[j]-fx[j])/dx
      else
        deriv <<= f.zero
      end
    end
    x[i] = xSave
  end
  deriv
end
isEqual(a,b,zero=0.0,e=1.0e-8) click to toggle source

Determines the equality of two numbers by comparing to zero, or using the epsilon value

# File ext/bigdecimal/lib/bigdecimal/jacobian.rb, line 27
def isEqual(a,b,zero=0.0,e=1.0e-8)
  aa = a.abs
  bb = b.abs
  if aa == zero &&  bb == zero then
    true
  else
    if ((a-b)/(aa+bb)).abs < e then
      true
    else
      false
    end
  end
end
jacobian(f,fx,x) click to toggle source

Computes the Jacobian of f at x. fx is the value of f at x.

# File ext/bigdecimal/lib/bigdecimal/jacobian.rb, line 77
def jacobian(f,fx,x)
  n = x.size
  dfdx = Array::new(n*n)
  for i in 0...n do
    df = dfdxi(f,fx,x,i)
    for j in 0...n do
      dfdx[j*n+i] = df[j]
    end
  end
  dfdx
end


module Kconv - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Kconv

Kanji Converter for Ruby.

In Files

  • ext/nkf/lib/kconv.rb

Constants

ASCII

ASCII

AUTO

Auto-Detect

BINARY

BINARY

EUC

EUC-JP

JIS

ISO-2022-JP

NOCONV

NOCONV

SJIS

Shift_JIS

UNKNOWN

UNKNOWN

UTF16

UTF-16

UTF32

UTF-32

UTF8

UTF-8

Public Class Methods

guess(str) → encoding click to toggle source

Guess input encoding by NKF.guess

# File ext/nkf/lib/kconv.rb, line 140
def guess(str)
  ::NKF::guess(str)
end
iseuc(str) → true or false click to toggle source

Returns whether input encoding is EUC-JP or not.

Note don't expect this return value is MatchData.

# File ext/nkf/lib/kconv.rb, line 155
def iseuc(str)
  str.dup.force_encoding(EUC).valid_encoding?
end
isjis(str) → true or false click to toggle source

Returns whether input encoding is ISO-2022-JP or not.

# File ext/nkf/lib/kconv.rb, line 173
def isjis(str)
  /\A [\t\n\r\x20-\x7E]*
    (?:
      (?:\x1b \x28 I      [\x21-\x7E]*
        |\x1b \x28 J      [\x21-\x7E]*
        |\x1b \x24 @      (?:[\x21-\x7E]{2})*
        |\x1b \x24 B      (?:[\x21-\x7E]{2})*
        |\x1b \x24 \x28 D (?:[\x21-\x7E]{2})*
      )*
      \x1b \x28 B [\t\n\r\x20-\x7E]*
    )*
   \z/ox =~ str.dup.force_encoding('BINARY') ? true : false
end
issjis(str) → true or false click to toggle source

Returns whether input encoding is Shift_JIS or not.

# File ext/nkf/lib/kconv.rb, line 164
def issjis(str)
  str.dup.force_encoding(SJIS).valid_encoding?
end
isutf8(str) → true or false click to toggle source

Returns whether input encoding is UTF-8 or not.

# File ext/nkf/lib/kconv.rb, line 192
def isutf8(str)
  str.dup.force_encoding(UTF8).valid_encoding?
end
kconv(str, to_enc, from_enc=nil) click to toggle source

Convert str to to_enc. to_enc and from_enc are given as constants of Kconv or Encoding objects.

# File ext/nkf/lib/kconv.rb, line 56
def kconv(str, to_enc, from_enc=nil)
  opt = ''
  opt += ' --ic=' + from_enc.to_s if from_enc
  opt += ' --oc=' + to_enc.to_s if to_enc

  ::NKF::nkf(opt, str)
end
toeuc(str) → string click to toggle source

Convert str to EUC-JP

# File ext/nkf/lib/kconv.rb, line 82
def toeuc(str)
  kconv(str, EUC)
end
tojis(str) → string click to toggle source

Convert str to ISO-2022-JP

# File ext/nkf/lib/kconv.rb, line 73
def tojis(str)
  kconv(str, JIS)
end
tolocale → string click to toggle source

Convert self to locale encoding

# File ext/nkf/lib/kconv.rb, line 127
def tolocale(str)
  kconv(str, Encoding.locale_charmap)
end
tosjis(str) → string click to toggle source

Convert str to Shift_JIS

# File ext/nkf/lib/kconv.rb, line 91
def tosjis(str)
  kconv(str, SJIS)
end
toutf16(str) → string click to toggle source

Convert str to UTF-16

# File ext/nkf/lib/kconv.rb, line 109
def toutf16(str)
  kconv(str, UTF16)
end
toutf32(str) → string click to toggle source

Convert str to UTF-32

# File ext/nkf/lib/kconv.rb, line 118
def toutf32(str)
  kconv(str, UTF32)
end
toutf8(str) → string click to toggle source

Convert str to UTF-8

# File ext/nkf/lib/kconv.rb, line 100
def toutf8(str)
  kconv(str, UTF8)
end


module Kernel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Kernel

In Files

  • lib/minitest/spec.rb
  • lib/open-uri.rb
  • lib/pp.rb
  • lib/rubygems/core_ext/kernel_gem.rb
  • lib/rubygems/core_ext/kernel_require.rb
  • lib/scanf.rb
  • lib/uri/common.rb
  • ext/bigdecimal/bigdecimal.c
  • ext/json/lib/json/common.rb
  • ext/pathname/pathname.c
  • ext/psych/lib/psych/y.rb

Public Class Methods

URI(uri) click to toggle source

Returns uri converted to a URI object.

# File lib/uri/common.rb, line 992
def URI(uri)
  if uri.is_a?(URI::Generic)
    uri
  elsif uri = String.try_convert(uri)
    URI.parse(uri)
  else
    raise ArgumentError,
      "bad argument (expected URI object or URI string)"
  end
end
open(name, *rest, &block) click to toggle source

Allows the opening of various resources including URIs.

If the first argument responds to the 'open' method, 'open' is called on it with the rest of the arguments.

If the first argument is a string that begins with xxx://, it is parsed by URI.parse. If the parsed object responds to the 'open' method, 'open' is called on it with the rest of the arguments.

Otherwise, the original #open is called.

OpenURI::OpenRead#open
provides OpenURI::OpenRead#open,
URI::HTTPS#open and OpenURI::OpenRead#open, #open.

We can accept URIs and strings that begin with http://, https:// and ftp://. In these cases, the opened file object is extended by OpenURI::Meta.

# File lib/open-uri.rb, line 28
def open(name, *rest, &block) # :doc:
  if name.respond_to?(:open)
    name.open(*rest, &block)
  elsif name.respond_to?(:to_str) &&
        %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ name &&
        (uri = URI.parse(name)).respond_to?(:open)
    uri.open(*rest, &block)
  else
    open_uri_original_open(name, *rest, &block)
  end
end
Also aliased as: open_uri_original_open, open_uri_original_open
pp(*objs) click to toggle source

prints arguments in pretty form.

pp returns argument(s).

# File lib/pp.rb, line 13
def pp(*objs) # :doc:
  objs.each {|obj|
    PP.pp(obj)
  }
  objs.size <= 1 ? objs.first : objs
end

Public Instance Methods

BigDecimal(*args) click to toggle source
static VALUE
BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
{
    ENTER(1);
    Real *pv;

    GUARD_OBJ(pv, BigDecimal_new(argc, argv));
    if (ToValue(pv)) pv = VpCopy(NULL, pv);
    pv->obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, pv);
    return pv->obj;
}
Pathname(p1) click to toggle source

Creates a new Pathname object.

static VALUE
path_f_pathname(VALUE self, VALUE str)
{
    return rb_class_new_instance(1, &str, rb_cPathname);
}
gem_original_require(path) click to toggle source

The Kernel#require from before RubyGems was loaded.

Alias for: require
pretty_inspect() click to toggle source

returns a pretty printed object as a string.

# File lib/pp.rb, line 5
def pretty_inspect
  PP.pp(self, '')
end

Private Instance Methods

gem(gem_name, *requirements) click to toggle source

Use #gem to activate a specific version of gem_name.

requirements is a list of version requirements that the specified gem must match, most commonly “= example.version.number”. See Gem::Requirement for how to specify a version requirement.

If you will be activating the latest version of a gem, there is no need to call #gem, Kernel#require will do the right thing for you.

#gem returns true if the gem was activated, otherwise false. If the gem could not be found, didn't match the version requirements, or a different version was already activated, an exception will be raised.

#gem should be called before any require statements (otherwise RubyGems may load a conflicting library version).

In older RubyGems versions, the environment variable GEM_SKIP could be used to skip activation of specified gems, for example to test out changes that haven't been installed yet. Now RubyGems defers to -I and the RUBYLIB environment variable to skip activation of a gem.

Example:

GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb
# File lib/rubygems/core_ext/kernel_gem.rb, line 32
def gem(gem_name, *requirements) # :doc:
  skip_list = (ENV['GEM_SKIP'] || "").split(/:/)
  raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name

  if gem_name.kind_of? Gem::Dependency
    unless Gem::Deprecate.skip
      warn "#{Gem.location_of_caller.join ':'}:Warning: Kernel.gem no longer "           "accepts a Gem::Dependency object, please pass the name "           "and requirements directly"
    end

    requirements = gem_name.requirement
    gem_name = gem_name.name
  end

  spec = Gem::Dependency.new(gem_name, *requirements).to_spec
  spec.activate if spec
end
open(name, *rest, &block) click to toggle source

Allows the opening of various resources including URIs.

If the first argument responds to the 'open' method, 'open' is called on it with the rest of the arguments.

If the first argument is a string that begins with xxx://, it is parsed by URI.parse. If the parsed object responds to the 'open' method, 'open' is called on it with the rest of the arguments.

Otherwise, the original #open is called.

OpenURI::OpenRead#open
provides OpenURI::OpenRead#open,
URI::HTTPS#open and OpenURI::OpenRead#open, #open.

We can accept URIs and strings that begin with http://, https:// and ftp://. In these cases, the opened file object is extended by OpenURI::Meta.

# File lib/open-uri.rb, line 28
def open(name, *rest, &block) # :doc:
  if name.respond_to?(:open)
    name.open(*rest, &block)
  elsif name.respond_to?(:to_str) &&
        %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ name &&
        (uri = URI.parse(name)).respond_to?(:open)
    uri.open(*rest, &block)
  else
    open_uri_original_open(name, *rest, &block)
  end
end
Also aliased as: open_uri_original_open, open_uri_original_open
pp(*objs) click to toggle source

prints arguments in pretty form.

pp returns argument(s).

# File lib/pp.rb, line 13
def pp(*objs) # :doc:
  objs.each {|obj|
    PP.pp(obj)
  }
  objs.size <= 1 ? objs.first : objs
end
scanf(format, &b) click to toggle source

Scans STDIN for data matching format. See IO#scanf for details.

See Scanf for details on creating a format string.

You will need to require 'scanf' to use #scanf.

# File lib/scanf.rb, line 768
def scanf(format, &b) #:doc:
  STDIN.scanf(format ,&b)
end


module LUSolve - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module LUSolve

Solves a*x = b for x, using LU decomposition.

In Files

  • ext/bigdecimal/lib/bigdecimal/ludcmp.rb

Public Instance Methods

ludecomp(a,n,zero=0,one=1) click to toggle source

Performs LU decomposition of the n by n matrix a.

# File ext/bigdecimal/lib/bigdecimal/ludcmp.rb, line 10
  def ludecomp(a,n,zero=0,one=1)
    prec = BigDecimal.limit(nil)
    ps     = []
    scales = []
    for i in 0...n do  # pick up largest(abs. val.) element in each row.
      ps <<= i
      nrmrow  = zero
      ixn = i*n
      for j in 0...n do
        biggst = a[ixn+j].abs
        nrmrow = biggst if biggst>nrmrow
      end
      if nrmrow>zero then
        scales <<= one.div(nrmrow,prec)
      else
        raise "Singular matrix"
      end
    end
    n1          = n - 1
    for k in 0...n1 do # Gaussian elimination with partial pivoting.
      biggst  = zero;
      for i in k...n do
        size = a[ps[i]*n+k].abs*scales[ps[i]]
        if size>biggst then
          biggst = size
          pividx  = i
        end
      end
      raise "Singular matrix" if biggst<=zero
      if pividx!=k then
        j = ps[k]
        ps[k] = ps[pividx]
        ps[pividx] = j
      end
      pivot   = a[ps[k]*n+k]
      for i in (k+1)...n do
        psin = ps[i]*n
        a[psin+k] = mult = a[psin+k].div(pivot,prec)
        if mult!=zero then
          pskn = ps[k]*n
          for j in (k+1)...n do
            a[psin+j] -= mult.mult(a[pskn+j],prec)
          end
        end
      end
    end
    raise "Singular matrix" if a[ps[n1]*n+n1] == zero
    ps
  end

  # Solves a*x = b for x, using LU decomposition.
  #
  # a is a matrix, b is a constant vector, x is the solution vector.
  #
  # ps is the pivot, a vector which indicates the permutation of rows performed
  # during LU decomposition.
  def lusolve(a,b,ps,zero=0.0)
    prec = BigDecimal.limit(nil)
    n = ps.size
    x = []
    for i in 0...n do
      dot = zero
      psin = ps[i]*n
      for j in 0...i do
        dot = a[psin+j].mult(x[j],prec) + dot
      end
      x <<= b[ps[i]] - dot
    end
    (n-1).downto(0) do |i|
      dot = zero
      psin = ps[i]*n
      for j in (i+1)...n do
        dot = a[psin+j].mult(x[j],prec) + dot
      end
      x[i]  = (x[i]-dot).div(a[psin+i],prec)
    end
    x
  end
end
lusolve(a,b,ps,zero=0.0) click to toggle source

Solves a*x = b for x, using LU decomposition.

a is a matrix, b is a constant vector, x is the solution vector.

ps is the pivot, a vector which indicates the permutation of rows performed during LU decomposition.

# File ext/bigdecimal/lib/bigdecimal/ludcmp.rb, line 66
  def lusolve(a,b,ps,zero=0.0)
    prec = BigDecimal.limit(nil)
    n = ps.size
    x = []
    for i in 0...n do
      dot = zero
      psin = ps[i]*n
      for j in 0...i do
        dot = a[psin+j].mult(x[j],prec) + dot
      end
      x <<= b[ps[i]] - dot
    end
    (n-1).downto(0) do |i|
      dot = zero
      psin = ps[i]*n
      for j in (i+1)...n do
        dot = a[psin+j].mult(x[j],prec) + dot
      end
      x[i]  = (x[i]-dot).div(a[psin+i],prec)
    end
    x
  end
end


class Logger - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Logger

Description

The Logger class provides a simple but sophisticated logging utility that you can use to output messages.

The messages have associated levels, such as INFO or ERROR that indicate their importance. You can then give the Logger a level, and only messages at that level or higher will be printed.

The levels are:

UNKNOWN

An unknown message that should always be logged.

FATAL

An unhandleable error that results in a program crash.

ERROR

A handleable error condition.

WARN

A warning.

INFO

Generic (useful) information about system operation.

DEBUG

Low-level information for developers.

For instance, in a production system, you may have your Logger set to INFO or even WARN. When you are developing the system, however, you probably want to know about the program's internal state, and would set the Logger to DEBUG.

Note: Logger does not escape or sanitize any messages passed to it. Developers should be aware of when potentially malicious data (user-input) is passed to Logger, and manually escape the untrusted data:

logger.info("User-input: #{input.dump}")
logger.info("User-input: %p" % input)

You can use formatter= for escaping all data.

original_formatter = Logger::Formatter.new
logger.formatter = proc { |severity, datetime, progname, msg|
  original_formatter.call(severity, datetime, progname, msg.dump)
}
logger.info(input)

Example

This creates a Logger that outputs to the standard output stream, with a level of WARN:

require 'logger'

logger = Logger.new(STDOUT)
logger.level = Logger::WARN

logger.debug("Created logger")
logger.info("Program started")
logger.warn("Nothing to do!")

path = "a_non_existent_file"

begin
  File.foreach(path) do |line|
    unless line =~ /^(\w+) = (.*)$/
      logger.error("Line in wrong format: #{line.chomp}")
    end
  end
rescue => err
  logger.fatal("Caught exception; exiting")
  logger.fatal(err)
end

Because the Logger's level is set to WARN, only the warning, error, and fatal messages are recorded. The debug and info messages are silently discarded.

Features

There are several interesting features that Logger provides, like auto-rolling of log files, setting the format of log messages, and specifying a program name in conjunction with the message. The next section shows you how to achieve these things.

HOWTOs

How to create a logger

The options below give you various choices, in more or less increasing complexity.

  1. Create a logger which logs messages to STDERR/STDOUT.

    logger = Logger.new(STDERR)
logger = Logger.new(STDOUT)

  2. Create a logger for the file which has the specified name.

    logger = Logger.new('logfile.log')

  3. Create a logger for the specified file.

    file = File.open('foo.log', File::WRONLY | File::APPEND)
# To create new (and to remove old) logfile, add File::CREAT like:
# file = File.open('foo.log', File::WRONLY | File::APPEND | File::CREAT)
logger = Logger.new(file)

  4. Create a logger which ages the logfile once it reaches a certain size. Leave 10 “old” log files where each file is about 1,024,000 bytes.

    logger = Logger.new('foo.log', 10, 1024000)

  5. Create a logger which ages the logfile daily/weekly/monthly.

    logger = Logger.new('foo.log', 'daily')
logger = Logger.new('foo.log', 'weekly')
logger = Logger.new('foo.log', 'monthly')

How to log a message

Notice the different methods (fatal, error, info) being used to log messages of various levels? Other methods in this family are warn and debug. add is used below to log a message of an arbitrary (perhaps dynamic) level.

  1. Message in a block.

    logger.fatal { "Argument 'foo' not given." }

  2. Message as a string.

    logger.error "Argument #{@foo} mismatch."

  3. With progname.

    logger.info('initialize') { "Initializing..." }

  4. With severity.

    logger.add(Logger::FATAL) { 'Fatal error!' }

The block form allows you to create potentially complex log messages, but to delay their evaluation until and unless the message is logged. For example, if we have the following:

logger.debug { "This is a " + potentially + " expensive operation" }

If the logger's level is INFO or higher, no debug messages will be logged, and the entire block will not even be evaluated. Compare to this:

logger.debug("This is a " + potentially + " expensive operation")

Here, the string concatenation is done every time, even if the log level is not set to show the debug message.

How to close a logger

logger.close

Setting severity threshold

  1. Original interface.

    logger.sev_threshold = Logger::WARN

  2. Log4r (somewhat) compatible interface.

    logger.level = Logger::INFO

# DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN

Format

Log messages are rendered in the output stream in a certain format by default. The default format and a sample are shown below:

Log format:

SeverityID, [DateTime #pid] SeverityLabel -- ProgName: message

Log sample:

I, [1999-03-03T02:34:24.895701 #19074]  INFO -- Main: info.

You may change the date and time format via datetime_format=.

logger.datetime_format = '%Y-%m-%d %H:%M:%S'
      # e.g. "2004-01-03 00:54:26"

Or, you may change the overall format via the formatter= method.

logger.formatter = proc do |severity, datetime, progname, msg|
  "#{datetime}: #{msg}\n"
end
# e.g. "2005-09-22 08:51:08 +0900: hello world"

In Files

  • lib/logger.rb

Parent

Object

Included Modules

  • Logger::Severity

Constants

ProgName
SEV_LABEL

Severity label for logging (max 5 chars).

VERSION

Attributes

formatter[RW]

Logging formatter, as a Proc that will take four arguments and return the formatted message. The arguments are:

severity

The Severity of the log message.

time

A Time instance representing when the message was logged.

progname

The progname configured, or passed to the logger method.

msg

The Object the user passed to the log message; not necessarily a String.

The block should return an Object that can be written to the logging device via write. The default formatter is used when no formatter is set.

level[RW]

Logging severity threshold (e.g. Logger::INFO).

progname[RW]

Program name to include in log messages.

sev_threshold[RW]

Logging severity threshold (e.g. Logger::INFO).

sev_threshold=[RW]

Logging severity threshold (e.g. Logger::INFO).

Public Class Methods

new(name, shift_age = 7, shift_size = 1048576) click to toggle source
new(name, shift_age = 'weekly')

Args

logdev

The log device. This is a filename (String) or IO object (typically STDOUT, STDERR, or an open file).

shift_age

Number of old log files to keep, or frequency of rotation (daily, weekly or monthly).

shift_size

Maximum logfile size (only applies when shift_age is a number).

Description

Create an instance.

# File lib/logger.rb, line 311
def initialize(logdev, shift_age = 0, shift_size = 1048576)
  @progname = nil
  @level = DEBUG
  @default_formatter = Formatter.new
  @formatter = nil
  @logdev = nil
  if logdev
    @logdev = LogDevice.new(logdev, :shift_age => shift_age,
      :shift_size => shift_size)
  end
end

Public Instance Methods

<<(msg) click to toggle source

Dump given message to the log device without any formatting. If no log device exists, return nil.

# File lib/logger.rb, line 390
def <<(msg)
  unless @logdev.nil?
    @logdev.write(msg)
  end
end
Logger#add(severity, message = nil, progname = nil) { ... } click to toggle source

Args

severity

Severity. Constants are defined in Logger namespace: DEBUG, INFO, WARN, ERROR, FATAL, or UNKNOWN.

message

The log message. A String or Exception.

progname

Program name string. Can be omitted. Treated as a message if no message and block are given.

block

Can be omitted. Called to get a message string if message is nil.

Return

true if successful, false otherwise.

When the given severity is not high enough (for this particular logger), log no message, and return true.

Description

Log a message if the given severity is high enough. This is the generic logging method. Users will be more inclined to use debug, info, warn, error, and fatal.

Message format: message can be any object, but it has to be converted to a String in order to log it. Generally, inspect is used if the given object is not a String. A special case is an Exception object, which will be printed in detail, including message, class, and backtrace. See msg2str for the implementation if required.

Bugs

  • Logfile is not locked.

  • Append open does not need to lock file.

  • If the OS supports multi I/O, records possibly may be mixed.

# File lib/logger.rb, line 366
def add(severity, message = nil, progname = nil, &block)
  severity ||= UNKNOWN
  if @logdev.nil? or severity < @level
    return true
  end
  progname ||= @progname
  if message.nil?
    if block_given?
      message = yield
    else
      message = progname
      progname = @progname
    end
  end
  @logdev.write(
    format_message(format_severity(severity), Time.now, progname, message))
  true
end
Also aliased as: log
close() click to toggle source

Close the logging device.

# File lib/logger.rb, line 479
def close
  @logdev.close if @logdev
end
datetime_format() click to toggle source

Returns the date format being used. See datetime_format=

# File lib/logger.rb, line 250
def datetime_format
  @default_formatter.datetime_format
end
datetime_format=(datetime_format) click to toggle source

Set date-time format.

datetime_format

A string suitable for passing to strftime.

# File lib/logger.rb, line 245
def datetime_format=(datetime_format)
  @default_formatter.datetime_format = datetime_format
end
debug(progname = nil, &block) click to toggle source

Log a DEBUG message.

See info for more information.

# File lib/logger.rb, line 401
def debug(progname = nil, &block)
  add(DEBUG, nil, progname, &block)
end
debug?() click to toggle source

Returns true iff the current severity level allows for the printing of DEBUG messages.

# File lib/logger.rb, line 273
def debug?; @level <= DEBUG; end
error(progname = nil, &block) click to toggle source

Log an ERROR message.

See info for more information.

# File lib/logger.rb, line 453
def error(progname = nil, &block)
  add(ERROR, nil, progname, &block)
end
error?() click to toggle source

Returns true iff the current severity level allows for the printing of ERROR messages.

# File lib/logger.rb, line 285
def error?; @level <= ERROR; end
fatal(progname = nil, &block) click to toggle source

Log a FATAL message.

See info for more information.

# File lib/logger.rb, line 462
def fatal(progname = nil, &block)
  add(FATAL, nil, progname, &block)
end
fatal?() click to toggle source

Returns true iff the current severity level allows for the printing of FATAL messages.

# File lib/logger.rb, line 289
def fatal?; @level <= FATAL; end
info(message) click to toggle source
info(progname, &block)

Log an INFO message.

message

The message to log; does not need to be a String.

progname

In the block form, this is the progname to use in the log message. The default can be set with progname=.

block

Evaluates to the message to log. This is not evaluated unless the logger's level is sufficient to log the message. This allows you to create potentially expensive logging messages that are only called when the logger is configured to show them.

Examples

logger.info("MainApp") { "Received connection from #{ip}" }
# ...
logger.info "Waiting for input from user"
# ...
logger.info { "User typed #{input}" }

You'll probably stick to the second form above, unless you want to provide a program name (which you can do with progname= as well).

Return

See add.

# File lib/logger.rb, line 435
def info(progname = nil, &block)
  add(INFO, nil, progname, &block)
end
info?() click to toggle source

Returns true iff the current severity level allows for the printing of INFO messages.

# File lib/logger.rb, line 277
def info?; @level <= INFO; end
log(severity, message = nil, progname = nil, &block) click to toggle source
Alias for: add
unknown(progname = nil, &block) click to toggle source

Log an UNKNOWN message. This will be printed no matter what the logger's level is.

See info for more information.

# File lib/logger.rb, line 472
def unknown(progname = nil, &block)
  add(UNKNOWN, nil, progname, &block)
end
warn(progname = nil, &block) click to toggle source

Log a WARN message.

See info for more information.

# File lib/logger.rb, line 444
def warn(progname = nil, &block)
  add(WARN, nil, progname, &block)
end
warn?() click to toggle source

Returns true iff the current severity level allows for the printing of WARN messages.

# File lib/logger.rb, line 281
def warn?; @level <= WARN; end


class Logger::Application - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Logger::Application

Description

Application — Add logging support to your application.

Usage

  1. Define your application class as a sub-class of this class.

  2. Override the run method in your class to do many things.

  3. Instantiate it and invoke start.

Example

class FooApp < Application
  def initialize(foo_app, application_specific, arguments)
    super('FooApp') # Name of the application.
  end

  def run
    ...
    log(WARN, 'warning', 'my_method1')
    ...
    @log.error('my_method2') { 'Error!' }
    ...
  end
end

status = FooApp.new(....).start

In Files

  • lib/logger.rb

Parent

Object

Included Modules

  • Logger::Severity

Attributes

appname[R]

Name of the application given at initialize.

Public Class Methods

new(appname = '') click to toggle source

Args

appname

Name of the application.

Description

Create an instance. Log device is STDERR by default. This can be changed with set_log.

# File lib/logger.rb, line 728
def initialize(appname = nil)
  @appname = appname
  @log = Logger.new(STDERR)
  @log.progname = @appname
  @level = @log.level
end

Public Instance Methods

level=(level) click to toggle source

Set the logging threshold, just like Logger#level=.

# File lib/logger.rb, line 783
def level=(level)
  @level = level
  @log.level = @level
end
log(severity, message = nil, &block) click to toggle source

See Logger#add. This application's appname is used.

# File lib/logger.rb, line 791
def log(severity, message = nil, &block)
  @log.add(severity, message, @appname, &block) if @log
end
log=(logdev) click to toggle source
# File lib/logger.rb, line 776
def log=(logdev)
  set_log(logdev)
end
logger() click to toggle source

Logger for this application. See the class Logger for an explanation.

# File lib/logger.rb, line 752
def logger
  @log
end
logger=(logger) click to toggle source

Sets the logger for this application. See the class Logger for an explanation.

# File lib/logger.rb, line 760
def logger=(logger)
  @log = logger
  @log.progname = @appname
  @log.level = @level
end
set_log(logdev, shift_age = 0, shift_size = 1024000) click to toggle source

Sets the log device for this application. See Logger.new for an explanation of the arguments.

# File lib/logger.rb, line 770
def set_log(logdev, shift_age = 0, shift_size = 1024000)
  @log = Logger.new(logdev, shift_age, shift_size)
  @log.progname = @appname
  @log.level = @level
end
start() click to toggle source

Start the application. Return the status code.

# File lib/logger.rb, line 738
def start
  status = -1
  begin
    log(INFO, "Start of #{ @appname }.")
    status = run
  rescue
    log(FATAL, "Detected an exception. Stopping ... #{$!} (#{$!.class})\n" << $@.join("\n"))
  ensure
    log(INFO, "End of #{ @appname }. (status: #{ status.to_s })")
  end
  status
end


class Logger::Formatter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Logger::Formatter

Default formatter for log messages.

In Files

  • lib/logger.rb

Parent

Object

Constants

Format

Attributes

datetime_format[RW]

Public Class Methods

new() click to toggle source
# File lib/logger.rb, line 503
def initialize
  @datetime_format = nil
end

Public Instance Methods

call(severity, time, progname, msg) click to toggle source
# File lib/logger.rb, line 507
def call(severity, time, progname, msg)
  Format % [severity[0..0], format_datetime(time), $$, severity, progname,
    msg2str(msg)]
end


class Logger::LogDevice - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Logger::LogDevice

Device used for logging messages.

In Files

  • lib/logger.rb

Parent

Object

Constants

SiD

Attributes

dev[R]
filename[R]

Public Class Methods

new(log = nil, opt = {}) click to toggle source
# File lib/logger.rb, line 545
def initialize(log = nil, opt = {})
  @dev = @filename = @shift_age = @shift_size = nil
  @mutex = LogDeviceMutex.new
  if log.respond_to?(:write) and log.respond_to?(:close)
    @dev = log
  else
    @dev = open_logfile(log)
    @dev.sync = true
    @filename = log
    @shift_age = opt[:shift_age] || 7
    @shift_size = opt[:shift_size] || 1048576
  end
end

Public Instance Methods

close() click to toggle source
# File lib/logger.rb, line 580
def close
  begin
    @mutex.synchronize do
      @dev.close rescue nil
    end
  rescue Exception
    @dev.close rescue nil
  end
end
write(message) click to toggle source
# File lib/logger.rb, line 559
def write(message)
  begin
    @mutex.synchronize do
      if @shift_age and @dev.respond_to?(:stat)
        begin
          check_shift_log
        rescue
          warn("log shifting failed. #{$!}")
        end
      end
      begin
        @dev.write(message)
      rescue
        warn("log writing failed. #{$!}")
      end
    end
  rescue Exception => ignored
    warn("log writing failed. #{ignored}")
  end
end


class Logger::LogDevice::LogDeviceMutex - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Logger::LogDevice::LogDeviceMutex

In Files

  • lib/logger.rb

Parent

Object

Included Modules

  • MonitorMixin


module Logger::Severity - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Logger::Severity

Logging severity.

In Files

  • lib/logger.rb

Constants

DEBUG

Low-level information, mostly for developers.

ERROR

A handleable error condition.

FATAL

An unhandleable error that results in a program crash.

INFO

Generic (useful) information about system operation.

UNKNOWN

An unknown message that should always be logged.

WARN

A warning.


module MakeMakefile - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MakeMakefile

mkmf.rb is used by ruby C extensions to generate a Makefile which will correctly compile and link the C extension to ruby and a third-party library.

In Files

  • lib/mkmf.rb

Constants

CLEANINGS

Makefile rules that will clean the extension build directory

COMMON_HEADERS

Common headers for ruby C extensions

COMMON_LIBS

Common libraries for ruby C extensions

COMPILE_C

Command which will compile C files in the generated Makefile

COMPILE_CXX

Command which will compile C++ files in the generated Makefile

COMPILE_RULES

make compile rules

CONFIG

The makefile configuration using the defaults from when ruby was built.

CXX_EXT

Extensions for files complied with a C++ compiler

C_EXT

Extensions for files compiled with a C compiler

EXPORT_PREFIX
HDR_EXT

Extensions for header files

LIBARG

Argument which will add a library to the linker

LIBPATHFLAG

Argument which will add a library path to the linker

LINK_SO

Command which will link a shared library

MAIN_DOES_NOTHING

A C main function which does no work

ORIG_LIBPATH
RPATHFLAG
RULE_SUBST
SRC_EXT

Extensions for source files

TRY_LINK

Command which will compile a program in order to test linking a library

UNIVERSAL_INTS

Public Instance Methods

check_signedness(type, headers = nil, opts = nil, &b) click to toggle source

Returns the signedness of the given type. You may optionally specify additional headers to search in for the type.

If the type is found and is a numeric type, a macro is passed as a preprocessor constant to the compiler using the type name, in uppercase, prepended with SIGNEDNESS_OF_, followed by the type name, followed by =X where “X” is positive integer if the type is unsigned and a negative integer if the type is signed.

For example, if size_t is defined as unsigned, then check_signedness('size_t') would return +1 and the SIGNEDNESS_OF_SIZE_T=+1 preprocessor macro would be passed to the compiler. The SIGNEDNESS_OF_INT=-1 macro would be set for check_signedness('int')

# File lib/mkmf.rb, line 1307
def check_signedness(type, headers = nil, opts = nil, &b)
  typedef, member, prelude = typedef_expr(type, headers)
  signed = nil
  checking_for("signedness of #{type}", STRING_OR_FAILED_FORMAT) do
    signed = try_signedness(typedef, member, [prelude], opts, &b) or next nil
    $defs.push("-DSIGNEDNESS_OF_%s=%+d" % [type.tr_cpp, signed])
    signed < 0 ? "signed" : "unsigned"
  end
  signed
end
check_sizeof(type, headers = nil, opts = "", &b) click to toggle source

Returns the size of the given type. You may optionally specify additional headers to search in for the type.

If found, a macro is passed as a preprocessor constant to the compiler using the type name, in uppercase, prepended with SIZEOF_, followed by the type name, followed by =X where “X” is the actual size.

For example, if check_sizeof('mystruct') returned 12, then the SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.

# File lib/mkmf.rb, line 1278
def check_sizeof(type, headers = nil, opts = "", &b)
  typedef, member, prelude = typedef_expr(type, headers)
  prelude << "static #{typedef} *rbcv_ptr_;\n"
  prelude = [prelude]
  expr = "sizeof((*rbcv_ptr_)#{"." << member if member})"
  fmt = STRING_OR_FAILED_FORMAT
  checking_for checking_message("size of #{type}", headers), fmt do
    if size = try_constant(expr, prelude, opts, &b)
      $defs.push(format("-DSIZEOF_%s=%s", type.tr_cpp, size))
      size
    end
  end
end
convertible_int(type, headers = nil, opts = nil, &b) click to toggle source

Returns the convertible integer type of the given type. You may optionally specify additional headers to search in for the type. convertible means actually the same type, or typedef'd from the same type.

If the type is a integer type and the convertible type is found, the following macros are passed as preprocessor constants to the compiler using the type name, in uppercase.

  • TYPEOF_, followed by the type name, followed by =X where “X” is the found convertible type name.

  • TYP2NUM and NUM2TYP, where TYP is the type name in uppercase with replacing an _t suffix with “T”, followed by =X where “X” is the macro name to convert type to an Integer object, and vice versa.

For example, if foobar_t is defined as unsigned long, then convertible_int("foobar_t") would return “unsigned long”, and define these macros:

#define TYPEOF_FOOBAR_T unsigned long
#define FOOBART2NUM ULONG2NUM
#define NUM2FOOBART NUM2ULONG
# File lib/mkmf.rb, line 1342
def convertible_int(type, headers = nil, opts = nil, &b)
  type, macname = *type
  checking_for("convertible type of #{type}", STRING_OR_FAILED_FORMAT) do
    if UNIVERSAL_INTS.include?(type)
      type
    else
      typedef, member, prelude = typedef_expr(type, headers, &b)
      if member
        prelude << "static rbcv_typedef_ rbcv_var;"
        compat = UNIVERSAL_INTS.find {|t|
          try_static_assert("sizeof(rbcv_var.#{member}) == sizeof(#{t})", [prelude], opts, &b)
        }
      else
        next unless signed = try_signedness(typedef, member, [prelude])
        u = "unsigned " if signed > 0
        prelude << "extern rbcv_typedef_ foo();"
        compat = UNIVERSAL_INTS.find {|t|
          try_compile([prelude, "extern #{u}#{t} foo();"].join("\n"), opts, :werror=>true, &b)
        }
      end
      if compat
        macname ||= type.sub(/_(?=t\z)/, '').tr_cpp
        conv = (compat == "long long" ? "LL" : compat.upcase)
        compat = "#{u}#{compat}"
        typename = type.tr_cpp
        $defs.push(format("-DSIZEOF_%s=SIZEOF_%s", typename, compat.tr_cpp))
        $defs.push(format("-DTYPEOF_%s=%s", typename, compat.quote))
        $defs.push(format("-DPRI_%s_PREFIX=PRI_%s_PREFIX", macname, conv))
        conv = (u ? "U" : "") + conv
        $defs.push(format("-D%s2NUM=%s2NUM", macname, conv))
        $defs.push(format("-DNUM2%s=NUM2%s", macname, conv))
        compat
      end
    end
  end
end
create_header(header = "extconf.h") click to toggle source

Generates a header file consisting of the various macro definitions generated by other methods such as #have_func and have_header. These are then wrapped in a custom #ifndef based on the header file name, which defaults to “extconf.h”.

For example:

# extconf.rb
require 'mkmf'
have_func('realpath')
have_header('sys/utime.h')
create_header
create_makefile('foo')

The above script would generate the following extconf.h file:

#ifndef EXTCONF_H
#define EXTCONF_H
#define HAVE_REALPATH 1
#define HAVE_SYS_UTIME_H 1
#endif

Given that the #create_header method generates a file based on definitions set earlier in your extconf.rb file, you will probably want to make this one of the last methods you call in your script.

# File lib/mkmf.rb, line 1633
def create_header(header = "extconf.h")
  message "creating %s\n", header
  sym = header.tr_cpp
  hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
  for line in $defs
    case line
    when /^-D([^=]+)(?:=(.*))?/
      hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0].gsub(/(?=\t+)/, "\\\n") : 1}\n"
    when /^-U(.*)/
      hdr << "#undef #$1\n"
    end
  end
  hdr << "#endif\n"
  hdr = hdr.join("")
  log_src(hdr, "#{header} is")
  unless (IO.read(header) == hdr rescue false)
    open(header, "wb") do |hfile|
      hfile.write(hdr)
    end
  end
  $extconf_h = header
end
create_makefile(target, srcprefix = nil) { |conf| ... } click to toggle source

Generates the Makefile for your extension, passing along any options and preprocessor constants that you may have generated through other methods.

The target name should correspond the name of the global function name defined within your C extension, minus the Init_. For example, if your C extension is defined as Init_foo, then your target would simply be “foo”.

If any “/” characters are present in the target name, only the last name is interpreted as the target name, and the rest are considered toplevel directory names, and the generated Makefile will be altered accordingly to follow that directory structure.

For example, if you pass “test/foo” as a target name, your extension will be installed under the “test” directory. This means that in order to load the file within a Ruby program later, that directory structure will have to be followed, e.g. require 'test/foo'.

The srcprefix should be used when your source files are not in the same directory as your build script. This will not only eliminate the need for you to manually copy the source files into the same directory as your build script, but it also sets the proper target_prefix in the generated Makefile.

Setting the target_prefix will, in turn, install the generated binary in a directory under your RbConfig::CONFIG['sitearchdir'] that mimics your local filesystem when you run make install.

For example, given the following file tree:

ext/
  extconf.rb
  test/
    foo.c

And given the following code:

create_makefile('test/foo', 'test')

That will set the target_prefix in the generated Makefile to “test”. That, in turn, will create the following file tree when installed via the make install command:

/path/to/ruby/sitearchdir/test/foo.so

It is recommended that you use this approach to generate your makefiles, instead of copying files around manually, because some third party libraries may depend on the target_prefix being set properly.

The srcprefix argument can be used to override the default source directory, i.e. the current directory. It is included as part of the VPATH and added to the list of INCFLAGS.

# File lib/mkmf.rb, line 2057
  def create_makefile(target, srcprefix = nil)
    $target = target
    libpath = $DEFLIBPATH|$LIBPATH
    message "creating Makefile\n"
    MakeMakefile.rm_f "conftest*"
    if CONFIG["DLEXT"] == $OBJEXT
      for lib in libs = $libs.split
        lib.sub!(/-l(.*)/, %Q"lib\\1.#{$LIBEXT}"%)
      end
      $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
    end

    if target.include?('/')
      target_prefix, target = File.split(target)
      target_prefix[0,0] = '/'
    else
      target_prefix = ""
    end

    srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
    RbConfig.expand(srcdir = srcprefix.dup)

    ext = ".#{$OBJEXT}"
    orig_srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
    if not $objs
      srcs = $srcs || orig_srcs
      objs = srcs.inject(Hash.new {[]}) {|h, f| h[File.basename(f, ".*") << ext] <<= f; h}
      $objs = objs.keys
      unless objs.delete_if {|b, f| f.size == 1}.empty?
        dups = objs.sort.map {|b, f|
          "#{b[/.*\./]}{#{f.collect {|n| n[/([^.]+)\z/]}.join(',')}}"
        }
        abort "source files duplication - #{dups.join(", ")}"
      end
    else
      $objs.collect! {|o| File.basename(o, ".*") << ext} unless $OBJEXT == "o"
      srcs = $srcs || $objs.collect {|o| o.chomp(ext) << ".c"}
    end
    $srcs = srcs

    hdrs = Dir[File.join(srcdir, "*.{#{HDR_EXT.join(%q{,})}}")]

    target = nil if $objs.empty?

    if target and EXPORT_PREFIX
      if File.exist?(File.join(srcdir, target + '.def'))
        deffile = "$(srcdir)/$(TARGET).def"
        unless EXPORT_PREFIX.empty?
          makedef = %Q{-pe "$_.sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
        end
      else
        makedef = %Q{-e "puts 'EXPORTS', '$(TARGET_ENTRY)'"}
      end
      if makedef
        $cleanfiles << '$(DEFFILE)'
        origdef = deffile
        deffile = "$(TARGET)-$(arch).def"
      end
    end
    origdef ||= ''

    if $extout and $INSTALLFILES
      $cleanfiles.concat($INSTALLFILES.collect {|files, dir|File.join(dir, files.sub(/\A\.\//, ''))})
      $distcleandirs.concat($INSTALLFILES.collect {|files, dir| dir})
    end

    if $extmk and not $extconf_h
      create_header
    end

    libpath = libpathflag(libpath)

    dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
    staticlib = target ? "$(TARGET).#$LIBEXT" : ""
    mfile = open("Makefile", "wb")
    conf = configuration(srcprefix)
    conf = yield(conf) if block_given?
    mfile.puts(conf)
    mfile.print "
libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
LIBPATH = #{libpath}
DEFFILE = #{deffile}

CLEANFILES = #{$cleanfiles.join(' ')}
DISTCLEANFILES = #{$distcleanfiles.join(' ')}
DISTCLEANDIRS = #{$distcleandirs.join(' ')}

extout = #{$extout && $extout.quote}
extout_prefix = #{$extout_prefix}
target_prefix = #{target_prefix}
LOCAL_LIBS = #{$LOCAL_LIBS}
LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
ORIG_SRCS = #{orig_srcs.collect(&File.method(:basename)).join(' ')}
SRCS = $(ORIG_SRCS) #{(srcs - orig_srcs).collect(&File.method(:basename)).join(' ')}
OBJS = #{$objs.join(" ")}
HDRS = #{hdrs.map{|h| '$(srcdir)/' + File.basename(h)}.join(' ')}
TARGET = #{target}
TARGET_NAME = #{target && target[/\A\w+/]}
TARGET_ENTRY = #{EXPORT_PREFIX || ''}Init_$(TARGET_NAME)
DLLIB = #{dllib}
EXTSTATIC = #{$static || ""}
STATIC_LIB = #{staticlib unless $static.nil?}
#{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""}
" #"
    # TODO: fixme
    install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
    n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET)'
    mfile.print "
TARGET_SO     = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
CLEANLIBS     = #{n}.#{CONFIG['DLEXT']} #{config_string('cleanlibs') {|t| t.gsub(/\$\*/) {n}}}
CLEANOBJS     = *.#{$OBJEXT} #{config_string('cleanobjs') {|t| t.gsub(/\$\*/, "$(TARGET)#{deffile ? '-$(arch)': ''}")} if target} *.bak

all:    #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
.PHONY: all install static install-so install-rb
.PHONY: clean clean-so clean-static clean-rb
"
    mfile.print CLEANINGS
    fsep = config_string('BUILD_FILE_SEPARATOR') {|s| s unless s == "/"}
    if fsep
      sep = ":/=#{fsep}"
      fseprepl = proc {|s|
        s = s.gsub("/", fsep)
        s = s.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
        s = s.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
      }
      rsep = ":#{fsep}=/"
    else
      fseprepl = proc {|s| s}
      sep = ""
      rsep = ""
    end
    dirs = []
    mfile.print "install: install-so install-rb\n\n"
    sodir = (dir = "$(RUBYARCHDIR)").dup
    mfile.print("install-so: ")
    if target
      f = "$(DLLIB)"
      dest = "#{dir}/#{f}"
      if $extout
        mfile.puts dest
        mfile.print "clean-so::\n"
        mfile.print "\t-$(Q)$(RM) #{fseprepl[dest]}\n"
        mfile.print "\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n"
      else
        mfile.print "#{f} #{timestamp_file(dir)}\n"
        mfile.print "\t$(INSTALL_PROG) #{fseprepl[f]} #{dir}\n"
        if defined?($installed_list)
          mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
        end
      end
      mfile.print "clean-static::\n"
      mfile.print "\t-$(Q)$(RM) $(STATIC_LIB)\n"
    else
      mfile.puts "Makefile"
    end
    mfile.print("install-rb: pre-install-rb install-rb-default\n")
    mfile.print("install-rb-default: pre-install-rb-default\n")
    mfile.print("pre-install-rb: Makefile\n")
    mfile.print("pre-install-rb-default: Makefile\n")
    for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
      files = install_files(mfile, i, nil, srcprefix) or next
      for dir, *files in files
        unless dirs.include?(dir)
          dirs << dir
          mfile.print "pre-install-rb#{sfx}: #{timestamp_file(dir)}\n"
        end
        for f in files
          dest = "#{dir}/#{File.basename(f)}"
          mfile.print("install-rb#{sfx}: #{dest}\n")
          mfile.print("#{dest}: #{f} #{timestamp_file(dir)}\n")
          mfile.print("\t$(Q) $(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $(@D#{sep})\n")
          if defined?($installed_list) and !$extout
            mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
          end
          if $extout
            mfile.print("clean-rb#{sfx}::\n")
            mfile.print("\t-$(Q)$(RM) #{fseprepl[dest]}\n")
          end
        end
      end
      mfile.print "pre-install-rb#{sfx}:\n"
      mfile.print("\t$(ECHO) installing#{sfx.sub(/^-/, " ")} #{target} libraries\n")
      if $extout
        dirs.uniq!
        unless dirs.empty?
          mfile.print("clean-rb#{sfx}::\n")
          for dir in dirs.sort_by {|d| -d.count('/')}
            mfile.print("\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n")
          end
        end
      end
    end
    dirs.unshift(sodir) if target and !dirs.include?(sodir)
    dirs.each do |d|
      t = timestamp_file(d)
      mfile.print "#{t}:\n\t$(Q) $(MAKEDIRS) #{d}\n\t$(Q) $(TOUCH) $@\n"
    end

    mfile.print <<-SITEINSTALL

site-install: site-install-so site-install-rb
site-install-so: install-so
site-install-rb: install-rb

    SITEINSTALL

    return unless target

    mfile.puts SRC_EXT.collect {|e| ".path.#{e} = $(VPATH)"} if $nmake == b
    mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
    mfile.print "\n"

    compile_command = "\n\t$(ECHO) compiling $(<#{rsep})\n\t$(Q) %s\n\n"
    CXX_EXT.each do |e|
      each_compile_rules do |rule|
        mfile.printf(rule, e, $OBJEXT)
        mfile.printf(compile_command, COMPILE_CXX)
      end
    end
    C_EXT.each do |e|
      each_compile_rules do |rule|
        mfile.printf(rule, e, $OBJEXT)
        mfile.printf(compile_command, COMPILE_C)
      end
    end

    mfile.print "$(RUBYARCHDIR)/" if $extout
    mfile.print "$(DLLIB): "
    mfile.print "$(DEFFILE) " if makedef
    mfile.print "$(OBJS) Makefile"
    mfile.print " #{timestamp_file('$(RUBYARCHDIR)')}" if $extout
    mfile.print "\n"
    mfile.print "\t$(ECHO) linking shared-object #{target_prefix.sub(/\A\/(.*)/, '\1/')}$(DLLIB)\n"
    mfile.print "\t-$(Q)$(RM) $(@#{sep})\n"
    link_so = LINK_SO.gsub(/^/, "\t$(Q) ")
    if srcs.any?(&%r\.(?:#{CXX_EXT.join('|')})\z".method(:===))
      link_so = link_so.sub(/\bLDSHARED\b/, '\&XX')
    end
    mfile.print link_so, "\n\n"
    unless $static.nil?
      mfile.print "$(STATIC_LIB): $(OBJS)\n\t-$(Q)$(RM) $(@#{sep})\n\t"
      mfile.print "$(ECHO) linking static-library $(@#{rsep})\n\t$(Q) "
      mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
      config_string('RANLIB') do |ranlib|
        mfile.print "\n\t-$(Q)#{ranlib} $(DLLIB) 2> /dev/null || true"
      end
    end
    mfile.print "\n\n"
    if makedef
      mfile.print "$(DEFFILE): #{origdef}\n"
      mfile.print "\t$(ECHO) generating $(@#{rsep})\n"
      mfile.print "\t$(Q) $(RUBY) #{makedef} #{origdef} > $@\n\n"
    end

    depend = File.join(srcdir, "depend")
    if File.exist?(depend)
      mfile.print("###\n", *depend_rules(File.read(depend)))
    else
      mfile.print "$(OBJS): $(HDRS) $(ruby_headers)\n"
    end

    $makefile_created = true
  ensure
    mfile.close if mfile
  end
depend_rules(depend) click to toggle source

Processes the data contents of the “depend” file. Each line of this file is expected to be a file name.

Returns the output of findings, in Makefile format.

# File lib/mkmf.rb, line 1948
def depend_rules(depend)
  suffixes = []
  depout = []
  cont = implicit = nil
  impconv = proc do
    each_compile_rules {|rule| depout << (rule % implicit[0]) << implicit[1]}
    implicit = nil
  end
  ruleconv = proc do |line|
    if implicit
      if /\A\t/ =~ line
        implicit[1] << line
        next
      else
        impconv[]
      end
    end
    if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
      suffixes << m[1] << m[2]
      implicit = [[m[1], m[2]], [m.post_match]]
      next
    elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
      line.gsub!(%r(\s)(?!\.)([^$(){}+=:\s\/\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
    end
    depout << line
  end
  depend.each_line do |line|
    line.gsub!(/\.o\b/, ".#{$OBJEXT}")
    line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h)
    line.gsub!(%r\$\(hdrdir\)/(?!ruby(?![^:;/\s]))(?=[-\w]+\.h)", '\&ruby/')
    if $nmake && /\A\s*\$\(RM|COPY\)/ =~ line
      line.gsub!(%r[-\w\./]{2,}"){$&.tr("/", "\\")}
      line.gsub!(/(\$\((?!RM|COPY)[^:)]+)(?=\))/, '\1:/=\')
    end
    if /(?:^|[^\])(?:\\)*\$/ =~ line
      (cont ||= []) << line
      next
    elsif cont
      line = (cont << line).join
      cont = nil
    end
    ruleconv.call(line)
  end
  if cont
    ruleconv.call(cont.join)
  elsif implicit
    impconv.call
  end
  unless suffixes.empty?
    depout.unshift(".SUFFIXES: ." + suffixes.uniq.join(" .") + "\n\n")
  end
  depout.unshift("$(OBJS): $(RUBY_EXTCONF_H)\n\n") if $extconf_h
  depout.flatten!
  depout
end
dir_config(target, idefault=nil, ldefault=nil) click to toggle source

Sets a target name that the user can then use to configure various “with” options with on the command line by using that name. For example, if the target is set to “foo”, then the user could use the --with-foo-dir command line option.

You may pass along additional “include” or “lib” defaults via the idefault and ldefault parameters, respectively.

Note that #dir_config only adds to the list of places to search for libraries and include files. It does not link the libraries into your application.

# File lib/mkmf.rb, line 1668
def dir_config(target, idefault=nil, ldefault=nil)
  if dir = with_config(target + "-dir", (idefault unless ldefault))
    defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
    idefault = ldefault = nil
  end

  idir = with_config(target + "-include", idefault)
  $arg_config.last[1] ||= "${#{target}-dir}/include"
  ldir = with_config(target + "-lib", ldefault)
  $arg_config.last[1] ||= "${#{target}-dir}/#{@libdir_basename}"

  idirs = idir ? Array === idir ? idir.dup : idir.split(File::PATH_SEPARATOR) : []
  if defaults
    idirs.concat(defaults.collect {|d| d + "/include"})
    idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
  end
  unless idirs.empty?
    idirs.collect! {|d| "-I" + d}
    idirs -= Shellwords.shellwords($CPPFLAGS)
    unless idirs.empty?
      $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
    end
  end

  ldirs = ldir ? Array === ldir ? ldir.dup : ldir.split(File::PATH_SEPARATOR) : []
  if defaults
    ldirs.concat(defaults.collect {|d| "#{d}/#{@libdir_basename}"})
    ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
  end
  $LIBPATH = ldirs | $LIBPATH

  [idir, ldir]
end
dummy_makefile(srcdir) click to toggle source

creates a stub Makefile.

# File lib/mkmf.rb, line 1918
  def dummy_makefile(srcdir)
    configuration(srcdir) << "CLEANFILES = #{$cleanfiles.join(' ')}
DISTCLEANFILES = #{$distcleanfiles.join(' ')}

all install static install-so install-rb: Makefile
.PHONY: all install static install-so install-rb
.PHONY: clean clean-so clean-static clean-rb

" << CLEANINGS
  end
enable_config(config, default=nil) { |config, default| ... } click to toggle source

Tests for the presence of an --enable-config or --disable-config option. Returns true if the enable option is given, false if the disable option is given, and the default value otherwise.

This can be useful for adding custom definitions, such as debug information.

Example:

if enable_config("debug")
   $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
end
# File lib/mkmf.rb, line 1595
def enable_config(config, default=nil)
  if arg_config("--enable-"+config)
    true
  elsif arg_config("--disable-"+config)
    false
  elsif block_given?
    yield(config, default)
  else
    return default
  end
end
find_executable(bin, path = nil) click to toggle source

Searches for the executable bin on path. The default path is your PATH environment variable. If that isn't defined, it will resort to searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.

If found, it will return the full path, including the executable name, of where it was found.

Note that this method does not actually affect the generated Makefile.

# File lib/mkmf.rb, line 1525
def find_executable(bin, path = nil)
  checking_for checking_message(bin, path) do
    find_executable0(bin, path)
  end
end
find_header(header, *paths) click to toggle source

Instructs mkmf to search for the given header in any of the paths provided, and returns whether or not it was found in those paths.

If the header is found then the path it was found on is added to the list of included directories that are sent to the compiler (via the -I switch).

# File lib/mkmf.rb, line 1092
def find_header(header, *paths)
  message = checking_message(header, paths)
  header = cpp_include(header)
  checking_for message do
    if try_header(header)
      true
    else
      found = false
      paths.each do |dir|
        opt = "-I#{dir}".quote
        if try_header(header, opt)
          $INCFLAGS << " " << opt
          found = true
          break
        end
      end
      found
    end
  end
end
find_library(lib, func, *paths, &b) click to toggle source

Returns whether or not the entry point func can be found within the library lib in one of the paths specified, where paths is an array of strings. If func is nil , then the main() function is used as the entry point.

If lib is found, then the path it was found on is added to the list of library paths searched and linked against.

# File lib/mkmf.rb, line 967
def find_library(lib, func, *paths, &b)
  func = "main" if !func or func.empty?
  lib = with_config(lib+'lib', lib)
  paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
  checking_for checking_message(func.funcall_style, LIBARG%lib) do
    libpath = $LIBPATH
    libs = append_library($libs, lib)
    begin
      until r = try_func(func, libs, &b) or paths.empty?
        $LIBPATH = libpath | [paths.shift]
      end
      if r
        $libs = libs
        libpath = nil
      end
    ensure
      $LIBPATH = libpath if libpath
    end
    r
  end
end
find_type(type, opt, *headers, &b) click to toggle source

Returns where the static type type is defined.

You may also pass additional flags to opt which are then passed along to the compiler.

See also have_type.

# File lib/mkmf.rb, line 1189
def find_type(type, opt, *headers, &b)
  opt ||= ""
  fmt = "not found"
  def fmt.%(x)
    x ? x.respond_to?(:join) ? x.join(",") : x : self
  end
  checking_for checking_message(type, nil, opt), fmt do
    headers.find do |h|
      try_type(type, h, opt, &b)
    end
  end
end
have_const(const, headers = nil, opt = "", &b) click to toggle source

Returns whether or not the constant const is defined. You may optionally pass the type of const as [const, type], such as:

have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")

You may also pass additional headers to check against in addition to the common header files, and additional flags to opt which are then passed along to the compiler.

If found, a macro is passed as a preprocessor constant to the compiler using the type name, in uppercase, prepended with HAVE_CONST_.

For example, if have_const('foo') returned true, then the HAVE_CONST_FOO preprocessor macro would be passed to the compiler.

# File lib/mkmf.rb, line 1237
def have_const(const, headers = nil, opt = "", &b)
  checking_for checking_message([*const].compact.join(' '), headers, opt) do
    try_const(const, headers, opt, &b)
  end
end
have_framework(fw, &b) click to toggle source

Returns whether or not the given framework can be found on your system. If found, a macro is passed as a preprocessor constant to the compiler using the framework name, in uppercase, prepended with HAVE_FRAMEWORK_.

For example, if have_framework('Ruby') returned true, then the HAVE_FRAMEWORK_RUBY preprocessor macro would be passed to the compiler.

If fw is a pair of the framework name and its header file name that header file is checked, instead of the normally used header file which is named same as the framework.

# File lib/mkmf.rb, line 1063
def have_framework(fw, &b)
  if Array === fw
    fw, header = *fw
  else
    header = "#{fw}.h"
  end
  checking_for fw do
    src = cpp_include("#{fw}/#{header}") << "\n" "int main(void){return 0;}"
    opt = " -framework #{fw}"
    if try_link(src, "-ObjC#{opt}", &b)
      $defs.push(format("-DHAVE_FRAMEWORK_%s", fw.tr_cpp))
      # TODO: non-worse way than this hack, to get rid of separating
      # option and its argument.
      $LDFLAGS << " -ObjC" unless /(\A|\s)-ObjC(\s|\z)/ =~ $LDFLAGS
      $LDFLAGS << opt
      true
    else
      false
    end
  end
end
have_func(func, headers = nil, opt = "", &b) click to toggle source

Returns whether or not the function func can be found in the common header files, or within any headers that you provide. If found, a macro is passed as a preprocessor constant to the compiler using the function name, in uppercase, prepended with HAVE_.

To check functions in an additional library, you need to check that library first using have_library(). The func shall be either mere function name or function name with arguments.

For example, if have_func('foo') returned true, then the HAVE_FOO preprocessor macro would be passed to the compiler.

# File lib/mkmf.rb, line 1001
def have_func(func, headers = nil, opt = "", &b)
  checking_for checking_message(func.funcall_style, headers, opt) do
    if try_func(func, $libs, headers, opt, &b)
      $defs << "-DHAVE_#{func.sans_arguments.tr_cpp}"
      true
    else
      false
    end
  end
end
have_header(header, preheaders = nil, opt = "", &b) click to toggle source

Returns whether or not the given header file can be found on your system. If found, a macro is passed as a preprocessor constant to the compiler using the header file name, in uppercase, prepended with HAVE_.

For example, if have_header('foo.h') returned true, then the HAVE_FOO_H preprocessor macro would be passed to the compiler.

# File lib/mkmf.rb, line 1041
def have_header(header, preheaders = nil, opt = "", &b)
  checking_for header do
    if try_header(cpp_include(preheaders)+cpp_include(header), opt, &b)
      $defs.push(format("-DHAVE_%s", header.tr_cpp))
      true
    else
      false
    end
  end
end
have_library(lib, func = nil, headers = nil, opt = "", &b) click to toggle source

Returns whether or not the given entry point func can be found within lib. If func is nil, the main() entry point is used by default. If found, it adds the library to list of libraries to be used when linking your extension.

If headers are provided, it will include those header files as the header files it looks in when searching for func.

The real name of the library to be linked can be altered by --with-FOOlib configuration option.

# File lib/mkmf.rb, line 941
def have_library(lib, func = nil, headers = nil, opt = "", &b)
  func = "main" if !func or func.empty?
  lib = with_config(lib+'lib', lib)
  checking_for checking_message(func.funcall_style, LIBARG%lib, opt) do
    if COMMON_LIBS.include?(lib)
      true
    else
      libs = append_library($libs, lib)
      if try_func(func, libs, headers, opt, &b)
        $libs = libs
        true
      else
        false
      end
    end
  end
end
have_macro(macro, headers = nil, opt = "", &b) click to toggle source

Returns whether or not macro is defined either in the common header files or within any headers you provide.

Any options you pass to opt are passed along to the compiler.

# File lib/mkmf.rb, line 924
def have_macro(macro, headers = nil, opt = "", &b)
  checking_for checking_message(macro, headers, opt) do
    macro_defined?(macro, cpp_include(headers), opt, &b)
  end
end
have_struct_member(type, member, headers = nil, opt = "", &b) click to toggle source

Returns whether or not the struct of type type contains member. If it does not, or the struct type can't be found, then false is returned. You may optionally specify additional headers in which to look for the struct (in addition to the common header files).

If found, a macro is passed as a preprocessor constant to the compiler using the type name and the member name, in uppercase, prepended with HAVE_.

For example, if have_struct_member('struct foo', 'bar') returned true, then the HAVE_STRUCT_FOO_BAR preprocessor macro would be passed to the compiler.

HAVE_ST_BAR is also defined for backward compatibility.

# File lib/mkmf.rb, line 1128
  def have_struct_member(type, member, headers = nil, opt = "", &b)
    checking_for checking_message("#{type}.#{member}", headers) do
      if try_compile("#{cpp_include(headers)}
/*top*/
int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
#{MAIN_DOES_NOTHING "s"}
", opt, &b)
        $defs.push(format("-DHAVE_%s_%s", type.tr_cpp, member.tr_cpp))
        $defs.push(format("-DHAVE_ST_%s", member.tr_cpp)) # backward compatibility
        true
      else
        false
      end
    end
  end
have_type(type, headers = nil, opt = "", &b) click to toggle source

Returns whether or not the static type type is defined. You may optionally pass additional headers to check against in addition to the common header files.

You may also pass additional flags to opt which are then passed along to the compiler.

If found, a macro is passed as a preprocessor constant to the compiler using the type name, in uppercase, prepended with HAVE_TYPE_.

For example, if have_type('foo') returned true, then the HAVE_TYPE_FOO preprocessor macro would be passed to the compiler.

# File lib/mkmf.rb, line 1176
def have_type(type, headers = nil, opt = "", &b)
  checking_for checking_message(type, headers, opt) do
    try_type(type, headers, opt, &b)
  end
end
have_var(var, headers = nil, opt = "", &b) click to toggle source

Returns whether or not the variable var can be found in the common header files, or within any headers that you provide. If found, a macro is passed as a preprocessor constant to the compiler using the variable name, in uppercase, prepended with HAVE_.

To check variables in an additional library, you need to check that library first using have_library().

For example, if have_var('foo') returned true, then the HAVE_FOO preprocessor macro would be passed to the compiler.

# File lib/mkmf.rb, line 1023
def have_var(var, headers = nil, opt = "", &b)
  checking_for checking_message(var, headers, opt) do
    if try_var(var, headers, opt, &b)
      $defs.push(format("-DHAVE_%s", var.tr_cpp))
      true
    else
      false
    end
  end
end
try_const(const, headers = nil, opt = "", &b) click to toggle source

Returns whether or not the constant const is defined.

See also have_const

# File lib/mkmf.rb, line 1206
  def try_const(const, headers = nil, opt = "", &b)
    const, type = *const
    if try_compile("#{cpp_include(headers)}
/*top*/
typedef #{type || 'int'} conftest_type;
conftest_type conftestval = #{type ? '' : '(int)'}#{const};
", opt, &b)
      $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
      true
    else
      false
    end
  end
try_type(type, headers = nil, opt = "", &b) click to toggle source

Returns whether or not the static type type is defined.

See also have_type

# File lib/mkmf.rb, line 1149
  def try_type(type, headers = nil, opt = "", &b)
    if try_compile("#{cpp_include(headers)}
/*top*/
typedef #{type} conftest_type;
int conftestval[sizeof(conftest_type)?1:-1];
", opt, &b)
      $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
      true
    else
      false
    end
  end
with_config(config, default=nil) { |config, default| ... } click to toggle source

Tests for the presence of a --with-config or --without-config option. Returns true if the with option is given, false if the without option is given, and the default value otherwise.

This can be useful for adding custom definitions, such as debug information.

Example:

if with_config("debug")
   $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
end
# File lib/mkmf.rb, line 1560
def with_config(config, default=nil)
  config = config.sub(/^--with[-_]/, '')
  val = arg_config("--with-"+config) do
    if arg_config("--without-"+config)
      false
    elsif block_given?
      yield(config, default)
    else
      break default
    end
  end
  case val
  when "yes"
    true
  when "no"
    false
  else
    val
  end
end


module MakeMakefile::Logging - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MakeMakefile::Logging

In Files

  • lib/mkmf.rb


module MakeMakefile::STRING_OR_FAILED_FORMAT - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MakeMakefile::STRING_OR_FAILED_FORMAT

In Files

  • lib/mkmf.rb


class MatchData - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class MatchData

In Files

  • lib/pp.rb

Parent

Object

Public Instance Methods

pretty_print(q) click to toggle source
# File lib/pp.rb, line 474
def pretty_print(q)
  nc = []
  self.regexp.named_captures.each {|name, indexes|
    indexes.each {|i| nc[i] = name }
  }
  q.object_group(self) {
    q.breakable
    q.seplist(0...self.size, lambda { q.breakable }) {|i|
      if i == 0
        q.pp self[i]
      else
        if nc[i]
          q.text nc[i]
        else
          q.pp i
        end
        q.text ':'
        q.pp self[i]
      end
    }
  }
end


module Math - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Math

When mathn is required, the Math module changes as follows:

Standard Math module behaviour:

Math.sqrt(4/9)     # => 0.0
Math.sqrt(4.0/9.0) # => 0.666666666666667
Math.sqrt(- 4/9)   # => Errno::EDOM: Numerical argument out of domain - sqrt

After require 'mathn', this is changed to:

require 'mathn'
Math.sqrt(4/9)      # => 2/3
Math.sqrt(4.0/9.0)  # => 0.666666666666667
Math.sqrt(- 4/9)    # => Complex(0, 2/3)

In Files

  • lib/mathn.rb

Public Class Methods

rsqrt(a) click to toggle source

Compute square root of a non negative number. This method is internally used by Math.sqrt.

# File lib/mathn.rb, line 255
def rsqrt(a)
  if a.kind_of?(Float)
    sqrt!(a)
  elsif a.kind_of?(Rational)
    rsqrt(a.numerator)/rsqrt(a.denominator)
  else
    src = a
    max = 2 ** 32
    byte_a = [src & 0xffffffff]
    # ruby's bug
    while (src >= max) and (src >>= 32)
      byte_a.unshift src & 0xffffffff
    end

    answer = 0
    main = 0
    side = 0
    for elm in byte_a
      main = (main << 32) + elm
      side <<= 16
      if answer != 0
        if main * 4  < side * side
          applo = main.div(side)
        else
          applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1
        end
      else
        applo = sqrt!(main).to_i + 1
      end

      while (x = (side + applo) * applo) > main
        applo -= 1
      end
      main -= x
      answer = (answer << 16) + applo
      side += applo * 2
    end
    if main == 0
      answer
    else
      sqrt!(a)
    end
  end
end
sqrt(a) click to toggle source

Computes the square root of a. It makes use of Complex and Rational to have no rounding errors if possible.

Math.sqrt(4/9)      # => 2/3
Math.sqrt(- 4/9)    # => Complex(0, 2/3)
Math.sqrt(4.0/9.0)  # => 0.666666666666667

# File lib/mathn.rb, line 226
  def sqrt(a)
    if a.kind_of?(Complex)
      abs = sqrt(a.real*a.real + a.imag*a.imag)
#      if not abs.kind_of?(Rational)
#        return a**Rational(1,2)
#      end
      x = sqrt((a.real + abs)/Rational(2))
      y = sqrt((-a.real + abs)/Rational(2))
#      if !(x.kind_of?(Rational) and y.kind_of?(Rational))
#        return a**Rational(1,2)
#      end
      if a.imag >= 0
        Complex(x, y)
      else
        Complex(x, -y)
      end
    elsif a.respond_to?(:nan?) and a.nan?
      a
    elsif a >= 0
      rsqrt(a)
    else
      Complex(0,rsqrt(-a))
    end
  end


class Matrix - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Matrix

The Matrix class represents a mathematical matrix. It provides methods for creating matrices, operating on them arithmetically and algebraically, and determining their mathematical properties (trace, rank, inverse, determinant).

Method Catalogue

To create a matrix:

  • Matrix

  • Matrix.[](*rows)

  • ::rows(rows, copy = true)

  • ::columns

  • ::build(#row_count, #column_count, &block)

  • ::diagonal

  • ::scalar(n, value)

  • ::identity

  • ::unit

  • Matrix.I(n)

  • ::zero

  • ::row_vector

  • ::column_vector

To access Matrix elements/columns/rows/submatrices/properties:

  • #[](i, j)

  • row_count (#row_size)

  • column_count (#column_size)

  • row(i)

  • column(j)

  • collect

  • map

  • each

  • each_with_index

  • find_index

  • minor(*param)

Properties of a matrix:

  • diagonal?

  • empty?

  • hermitian?

  • lower_triangular?

  • normal?

  • orthogonal?

  • permutation?

  • real?

  • regular?

  • singular?

  • square?

  • symmetric?

  • unitary?

  • upper_triangular?

  • zero?

Matrix arithmetic:

  • #*(m)

  • #+(m)

  • #-(m)

  • #/(m)

  • inverse

  • inv

  • #**

Matrix functions:

  • determinant

  • det

  • rank

  • round

  • trace

  • tr

  • transpose

  • t

Matrix decompositions:

  • eigen

  • eigensystem

  • lup

  • lup_decomposition

Complex arithmetic:

  • conj

  • conjugate

  • imag

  • imaginary

  • real

  • rect

  • rectangular

Conversion to other data types:

  • coerce(other)

  • row_vectors

  • column_vectors

  • to_a

String representations:

  • to_s

  • inspect

In Files

  • lib/matrix/eigenvalue_decomposition.rb
  • lib/matrix/lup_decomposition.rb
  • lib/matrix.rb

Parent

Object

Included Modules

  • Enumerable

Constants

SELECTORS

Attributes

column_count[R]

Returns the number of columns.

column_size[R]

Returns the number of columns.

rows[R]

instance creations

Public Class Methods

I(n) click to toggle source
Alias for: identity
[](*rows) click to toggle source

Creates a matrix where each argument is a row.

Matrix[ [25, 93], [-1, 66] ]
   =>  25 93
       -1 66

# File lib/matrix.rb, line 139
def Matrix.[](*rows)
  rows(rows, false)
end
build(row_count, column_count = row_count) { |i, j| ... } click to toggle source

Creates a matrix of size row_count x column_count. It fills the values by calling the given block, passing the current row and column. Returns an enumerator if no block is given.

m = Matrix.build(2, 4) {|row, col| col - row }
  => Matrix[[0, 1, 2, 3], [-1, 0, 1, 2]]
m = Matrix.build(3) { rand }
  => a 3x3 matrix with random elements

# File lib/matrix.rb, line 184
def Matrix.build(row_count, column_count = row_count)
  row_count = CoercionHelper.coerce_to_int(row_count)
  column_count = CoercionHelper.coerce_to_int(column_count)
  raise ArgumentError if row_count < 0 || column_count < 0
  return to_enum :build, row_count, column_count unless block_given?
  rows = Array.new(row_count) do |i|
    Array.new(column_count) do |j|
      yield i, j
    end
  end
  new rows, column_count
end
column_vector(column) click to toggle source

Creates a single-column matrix where the values of that column are as given in column.

Matrix.column_vector([4,5,6])
  => 4
     5
     6

# File lib/matrix.rb, line 269
def Matrix.column_vector(column)
  column = convert_to_array(column)
  new [column].transpose, 1
end
columns(columns) click to toggle source

Creates a matrix using columns as an array of column vectors.

Matrix.columns([[25, 93], [-1, 66]])
   =>  25 -1
       93 66

# File lib/matrix.rb, line 169
def Matrix.columns(columns)
  rows(columns, false).transpose
end
diagonal(*values) click to toggle source

Creates a matrix where the diagonal elements are composed of values.

Matrix.diagonal(9, 5, -3)
  =>  9  0  0
      0  5  0
      0  0 -3

# File lib/matrix.rb, line 204
def Matrix.diagonal(*values)
  size = values.size
  rows = Array.new(size) {|j|
    row = Array.new(size, 0)
    row[j] = values[j]
    row
  }
  new rows
end
empty(row_count = 0, column_count = 0) click to toggle source

Creates a empty matrix of row_count x column_count. At least one of row_count or column_count must be 0.

m = Matrix.empty(2, 0)
m == Matrix[ [], [] ]
  => true
n = Matrix.empty(0, 3)
n == Matrix.columns([ [], [], [] ])
  => true
m * n
  => Matrix[[0, 0, 0], [0, 0, 0]]

# File lib/matrix.rb, line 287
def Matrix.empty(row_count = 0, column_count = 0)
  raise ArgumentError, "One size must be 0" if column_count != 0 && row_count != 0
  raise ArgumentError, "Negative size" if column_count < 0 || row_count < 0

  new([[]]*row_count, column_count)
end
identity(n) click to toggle source

Creates an n by n identity matrix.

Matrix.identity(2)
  => 1 0
     0 1

# File lib/matrix.rb, line 231
def Matrix.identity(n)
  scalar(n, 1)
end
Also aliased as: unit, I
new(rows, column_count = rows[0].size) click to toggle source

::new is private; use ::rows, columns, [], etc… to create.

# File lib/matrix.rb, line 297
def initialize(rows, column_count = rows[0].size)
  # No checking is done at this point. rows must be an Array of Arrays.
  # column_count must be the size of the first row, if there is one,
  # otherwise it *must* be specified and can be any integer >= 0
  @rows = rows
  @column_count = column_count
end
row_vector(row) click to toggle source

Creates a single-row matrix where the values of that row are as given in row.

Matrix.row_vector([4,5,6])
  => 4 5 6

# File lib/matrix.rb, line 256
def Matrix.row_vector(row)
  row = convert_to_array(row)
  new [row]
end
rows(rows, copy = true) click to toggle source

Creates a matrix where rows is an array of arrays, each of which is a row of the matrix. If the optional argument copy is false, use the given arrays as the internal structure of the matrix without copying.

Matrix.rows([[25, 93], [-1, 66]])
   =>  25 93
       -1 66

# File lib/matrix.rb, line 151
def Matrix.rows(rows, copy = true)
  rows = convert_to_array(rows)
  rows.map! do |row|
    convert_to_array(row, copy)
  end
  size = (rows[0] || []).size
  rows.each do |row|
    raise ErrDimensionMismatch, "row size differs (#{row.size} should be #{size})" unless row.size == size
  end
  new rows, size
end
scalar(n, value) click to toggle source

Creates an n by n diagonal matrix where each diagonal element is value.

Matrix.scalar(2, 5)
  => 5 0
     0 5

# File lib/matrix.rb, line 221
def Matrix.scalar(n, value)
  diagonal(*Array.new(n, value))
end
unit(n) click to toggle source
Alias for: identity
zero(row_count, column_count = row_count) click to toggle source

Creates a zero matrix.

Matrix.zero(2)
  => 0 0
     0 0

# File lib/matrix.rb, line 245
def Matrix.zero(row_count, column_count = row_count)
  rows = Array.new(row_count){Array.new(column_count, 0)}
  new rows, column_count
end

Public Instance Methods

*(m) click to toggle source

Matrix multiplication.

Matrix[[2,4], [6,8]] * Matrix.identity(2)
  => 2 4
     6 8

# File lib/matrix.rb, line 805
def *(m) # m is matrix or vector or number
  case(m)
  when Numeric
    rows = @rows.collect {|row|
      row.collect {|e| e * m }
    }
    return new_matrix rows, column_count
  when Vector
    m = self.class.column_vector(m)
    r = self * m
    return r.column(0)
  when Matrix
    Matrix.Raise ErrDimensionMismatch if column_count != m.row_count

    rows = Array.new(row_count) {|i|
      Array.new(m.column_count) {|j|
        (0 ... column_count).inject(0) do |vij, k|
          vij + self[i, k] * m[k, j]
        end
      }
    }
    return new_matrix rows, m.column_count
  else
    return apply_through_coercion(m, __method__)
  end
end
**(other) click to toggle source

Matrix exponentiation. Equivalent to multiplying the matrix by itself N times. Non integer exponents will be handled by diagonalizing the matrix.

Matrix[[7,6], [3,9]] ** 2
  => 67 96
     48 99

# File lib/matrix.rb, line 972
def ** (other)
  case other
  when Integer
    x = self
    if other <= 0
      x = self.inverse
      return self.class.identity(self.column_count) if other == 0
      other = -other
    end
    z = nil
    loop do
      z = z ? z * x : x if other[0] == 1
      return z if (other >>= 1).zero?
      x *= x
    end
  when Numeric
    v, d, v_inv = eigensystem
    v * self.class.diagonal(*d.each(:diagonal).map{|e| e ** other}) * v_inv
  else
    Matrix.Raise ErrOperationNotDefined, "**", self.class, other.class
  end
end
+(m) click to toggle source

Matrix addition.

Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]
  =>  6  0
     -4 12

# File lib/matrix.rb, line 838
def +(m)
  case m
  when Numeric
    Matrix.Raise ErrOperationNotDefined, "+", self.class, m.class
  when Vector
    m = self.class.column_vector(m)
  when Matrix
  else
    return apply_through_coercion(m, __method__)
  end

  Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count and column_count == m.column_count

  rows = Array.new(row_count) {|i|
    Array.new(column_count) {|j|
      self[i, j] + m[i, j]
    }
  }
  new_matrix rows, column_count
end
-(m) click to toggle source

Matrix subtraction.

Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]
  => -8  2
      8  1

# File lib/matrix.rb, line 865
def -(m)
  case m
  when Numeric
    Matrix.Raise ErrOperationNotDefined, "-", self.class, m.class
  when Vector
    m = self.class.column_vector(m)
  when Matrix
  else
    return apply_through_coercion(m, __method__)
  end

  Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count and column_count == m.column_count

  rows = Array.new(row_count) {|i|
    Array.new(column_count) {|j|
      self[i, j] - m[i, j]
    }
  }
  new_matrix rows, column_count
end
/(other) click to toggle source

Matrix division (multiplication by the inverse).

Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]
  => -7  1
     -3 -6

# File lib/matrix.rb, line 892
def /(other)
  case other
  when Numeric
    rows = @rows.collect {|row|
      row.collect {|e| e / other }
    }
    return new_matrix rows, column_count
  when Matrix
    return self * other.inverse
  else
    return apply_through_coercion(other, __method__)
  end
end
==(other) click to toggle source

Returns true if and only if the two matrices contain equal elements.

# File lib/matrix.rb, line 767
def ==(other)
  return false unless Matrix === other &&
                      column_count == other.column_count # necessary for empty matrices
  rows == other.rows
end
[](i, j) click to toggle source

Returns element (i,j) of the matrix. That is: row i, column j.

# File lib/matrix.rb, line 313
def [](i, j)
  @rows.fetch(i){return nil}[j]
end
Also aliased as: element, component
clone() click to toggle source

Returns a clone of the matrix, so that the contents of each do not reference identical objects. There should be no good reason to do this since Matrices are immutable.

# File lib/matrix.rb, line 784
def clone
  new_matrix @rows.map(&:dup), column_count
end
coerce(other) click to toggle source

The coerce method provides support for Ruby type coercion. This coercion mechanism is used by Ruby to handle mixed-type numeric operations: it is intended to find a compatible common type between the two operands of the operator. See also Numeric#coerce.

# File lib/matrix.rb, line 1277
def coerce(other)
  case other
  when Numeric
    return Scalar.new(other), self
  else
    raise TypeError, "#{self.class} can't be coerced into #{other.class}"
  end
end
collect() { |e| ... } click to toggle source

Returns a matrix that is the result of iteration of the given block over all elements of the matrix.

Matrix[ [1,2], [3,4] ].collect { |e| e**2 }
  => 1  4
     9 16

# File lib/matrix.rb, line 381
def collect(&block) # :yield: e
  return to_enum(:collect) unless block_given?
  rows = @rows.collect{|row| row.collect(&block)}
  new_matrix rows, column_count
end
Also aliased as: map
column(j) { |e| ... } click to toggle source

Returns column vector number j of the matrix as a Vector (starting at 0 like an array). When a block is given, the elements of that vector are iterated.

# File lib/matrix.rb, line 358
def column(j) # :yield: e
  if block_given?
    return self if j >= column_count || j < -column_count
    row_count.times do |i|
      yield @rows[i][j]
    end
    self
  else
    return nil if j >= column_count || j < -column_count
    col = Array.new(row_count) {|i|
      @rows[i][j]
    }
    Vector.elements(col, false)
  end
end
column_vectors() click to toggle source

Returns an array of the column vectors of the matrix. See Vector.

# File lib/matrix.rb, line 1298
def column_vectors
  Array.new(column_count) {|i|
    column(i)
  }
end
component(i, j) click to toggle source
Alias for: []
conj() click to toggle source
Alias for: conjugate
conjugate() click to toggle source

Returns the conjugate of the matrix.

Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
  => 1+2i   i  0
        1   2  3
Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].conjugate
  => 1-2i  -i  0
        1   2  3

# File lib/matrix.rb, line 1223
def conjugate
  collect(&:conjugate)
end
Also aliased as: conj
det() click to toggle source
Alias for: determinant
det_e() click to toggle source
Alias for: determinant_e
determinant() click to toggle source

Returns the determinant of the matrix.

Beware that using Float values can yield erroneous results because of their lack of precision. Consider using exact types like Rational or BigDecimal instead.

Matrix[[7,6], [3,9]].determinant
  => 45

# File lib/matrix.rb, line 1009
def determinant
  Matrix.Raise ErrDimensionMismatch unless square?
  m = @rows
  case row_count
    # Up to 4x4, give result using Laplacian expansion by minors.
    # This will typically be faster, as well as giving good results
    # in case of Floats
  when 0
    +1
  when 1
    + m[0][0]
  when 2
    + m[0][0] * m[1][1] - m[0][1] * m[1][0]
  when 3
    m0, m1, m2 = m
    + m0[0] * m1[1] * m2[2] - m0[0] * m1[2] * m2[1]        - m0[1] * m1[0] * m2[2] + m0[1] * m1[2] * m2[0]        + m0[2] * m1[0] * m2[1] - m0[2] * m1[1] * m2[0]
  when 4
    m0, m1, m2, m3 = m
    + m0[0] * m1[1] * m2[2] * m3[3] - m0[0] * m1[1] * m2[3] * m3[2]        - m0[0] * m1[2] * m2[1] * m3[3] + m0[0] * m1[2] * m2[3] * m3[1]        + m0[0] * m1[3] * m2[1] * m3[2] - m0[0] * m1[3] * m2[2] * m3[1]        - m0[1] * m1[0] * m2[2] * m3[3] + m0[1] * m1[0] * m2[3] * m3[2]        + m0[1] * m1[2] * m2[0] * m3[3] - m0[1] * m1[2] * m2[3] * m3[0]        - m0[1] * m1[3] * m2[0] * m3[2] + m0[1] * m1[3] * m2[2] * m3[0]        + m0[2] * m1[0] * m2[1] * m3[3] - m0[2] * m1[0] * m2[3] * m3[1]        - m0[2] * m1[1] * m2[0] * m3[3] + m0[2] * m1[1] * m2[3] * m3[0]        + m0[2] * m1[3] * m2[0] * m3[1] - m0[2] * m1[3] * m2[1] * m3[0]        - m0[3] * m1[0] * m2[1] * m3[2] + m0[3] * m1[0] * m2[2] * m3[1]        + m0[3] * m1[1] * m2[0] * m3[2] - m0[3] * m1[1] * m2[2] * m3[0]        - m0[3] * m1[2] * m2[0] * m3[1] + m0[3] * m1[2] * m2[1] * m3[0]
  else
    # For bigger matrices, use an efficient and general algorithm.
    # Currently, we use the Gauss-Bareiss algorithm
    determinant_bareiss
  end
end
Also aliased as: det
determinant_e() click to toggle source

deprecated; use #determinant

# File lib/matrix.rb, line 1091
def determinant_e
  warn "#{caller(1)[0]}: warning: Matrix#determinant_e is deprecated; use #determinant"
  determinant
end
Also aliased as: det_e
diagonal?() click to toggle source

Returns true is this is a diagonal matrix. Raises an error if matrix is not square.

# File lib/matrix.rb, line 599
def diagonal?
  Matrix.Raise ErrDimensionMismatch unless square?
  each(:off_diagonal).all?(&:zero?)
end
each(which = :all) { |e| ... } click to toggle source

Yields all elements of the matrix, starting with those of the first row, or returns an Enumerator is no block given. Elements can be restricted by passing an argument:

  • :all (default): yields all elements

  • :diagonal: yields only elements on the diagonal

  • :off_diagonal: yields all elements except on the diagonal

  • :lower: yields only elements on or below the diagonal

  • :strict_lower: yields only elements below the diagonal

  • :strict_upper: yields only elements above the diagonal

  • :upper: yields only elements on or above the diagonal

    Matrix[ [1,2], [3,4] ].each { |e| puts e }

    # => prints the numbers 1 to 4

    Matrix[ [1,2], [3,4] ].each(:strict_lower).#to_a # => [3]

# File lib/matrix.rb, line 404
def each(which = :all) # :yield: e
  return to_enum :each, which unless block_given?
  last = column_count - 1
  case which
  when :all
    block = Proc.new
    @rows.each do |row|
      row.each(&block)
    end
  when :diagonal
    @rows.each_with_index do |row, row_index|
      yield row.fetch(row_index){return self}
    end
  when :off_diagonal
    @rows.each_with_index do |row, row_index|
      column_count.times do |col_index|
        yield row[col_index] unless row_index == col_index
      end
    end
  when :lower
    @rows.each_with_index do |row, row_index|
      0.upto([row_index, last].min) do |col_index|
        yield row[col_index]
      end
    end
  when :strict_lower
    @rows.each_with_index do |row, row_index|
      [row_index, column_count].min.times do |col_index|
        yield row[col_index]
      end
    end
  when :strict_upper
    @rows.each_with_index do |row, row_index|
      (row_index+1).upto(last) do |col_index|
        yield row[col_index]
      end
    end
  when :upper
    @rows.each_with_index do |row, row_index|
      row_index.upto(last) do |col_index|
        yield row[col_index]
      end
    end
  else
    raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
  end
  self
end
each_with_index(which = :all) { |e, row, column| ... } click to toggle source

Same as each, but the row index and column index in addition to the element

Matrix[ [1,2], [3,4] ].each_with_index do |e, row, col|
  puts "#{e} at #{row}, #{col}"
end
  # => Prints:
  #    1 at 0, 0
  #    2 at 0, 1
  #    3 at 1, 0
  #    4 at 1, 1

# File lib/matrix.rb, line 465
def each_with_index(which = :all) # :yield: e, row, column
  return to_enum :each_with_index, which unless block_given?
  last = column_count - 1
  case which
  when :all
    @rows.each_with_index do |row, row_index|
      row.each_with_index do |e, col_index|
        yield e, row_index, col_index
      end
    end
  when :diagonal
    @rows.each_with_index do |row, row_index|
      yield row.fetch(row_index){return self}, row_index, row_index
    end
  when :off_diagonal
    @rows.each_with_index do |row, row_index|
      column_count.times do |col_index|
        yield row[col_index], row_index, col_index unless row_index == col_index
      end
    end
  when :lower
    @rows.each_with_index do |row, row_index|
      0.upto([row_index, last].min) do |col_index|
        yield row[col_index], row_index, col_index
      end
    end
  when :strict_lower
    @rows.each_with_index do |row, row_index|
      [row_index, column_count].min.times do |col_index|
        yield row[col_index], row_index, col_index
      end
    end
  when :strict_upper
    @rows.each_with_index do |row, row_index|
      (row_index+1).upto(last) do |col_index|
        yield row[col_index], row_index, col_index
      end
    end
  when :upper
    @rows.each_with_index do |row, row_index|
      row_index.upto(last) do |col_index|
        yield row[col_index], row_index, col_index
      end
    end
  else
    raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
  end
  self
end
eigen() click to toggle source
Alias for: eigensystem
eigensystem() click to toggle source

Returns the Eigensystem of the matrix; see EigenvalueDecomposition.

m = Matrix[[1, 2], [3, 4]]
v, d, v_inv = m.eigensystem
d.diagonal? # => true
v.inv == v_inv # => true
(v * d * v_inv).round(5) == m # => true

# File lib/matrix.rb, line 1190
def eigensystem
  EigenvalueDecomposition.new(self)
end
Also aliased as: eigen
element(i, j) click to toggle source
Alias for: []
elements_to_f() click to toggle source
# File lib/matrix.rb, line 1311
def elements_to_f
  warn "#{caller(1)[0]}: warning: Matrix#elements_to_f is deprecated, use map(&:to_f)"
  map(&:to_f)
end
elements_to_i() click to toggle source
# File lib/matrix.rb, line 1316
def elements_to_i
  warn "#{caller(1)[0]}: warning: Matrix#elements_to_i is deprecated, use map(&:to_i)"
  map(&:to_i)
end
elements_to_r() click to toggle source
# File lib/matrix.rb, line 1321
def elements_to_r
  warn "#{caller(1)[0]}: warning: Matrix#elements_to_r is deprecated, use map(&:to_r)"
  map(&:to_r)
end
empty?() click to toggle source

Returns true if this is an empty matrix, i.e. if the number of rows or the number of columns is 0.

# File lib/matrix.rb, line 608
def empty?
  column_count == 0 || row_count == 0
end
eql?(other) click to toggle source
# File lib/matrix.rb, line 773
def eql?(other)
  return false unless Matrix === other &&
                      column_count == other.column_count # necessary for empty matrices
  rows.eql? other.rows
end
find_index(*args) click to toggle source
Alias for: index
hash() click to toggle source

Returns a hash-code for the matrix.

# File lib/matrix.rb, line 791
def hash
  @rows.hash
end
hermitian?() click to toggle source

Returns true is this is an hermitian matrix. Raises an error if matrix is not square.

# File lib/matrix.rb, line 616
def hermitian?
  Matrix.Raise ErrDimensionMismatch unless square?
  each_with_index(:upper).all? do |e, row, col|
    e == rows[col][row].conj
  end
end
imag() click to toggle source
Alias for: imaginary
imaginary() click to toggle source

Returns the imaginary part of the matrix.

Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
  => 1+2i  i  0
        1  2  3
Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].imaginary
  =>   2i  i  0
        0  0  0

# File lib/matrix.rb, line 1237
def imaginary
  collect(&:imaginary)
end
Also aliased as: imag
index(value, selector = :all) → [row, column] click to toggle source
index(selector = :all){ block } → [row, column]
index(selector = :all) → an_enumerator

The index method is specialized to return the index as [row, column] It also accepts an optional selector argument, see each for details.

Matrix[ [1,2], [3,4] ].index(&:even?) # => [0, 1]
Matrix[ [1,1], [1,1] ].index(1, :strict_lower) # => [1, 0]

# File lib/matrix.rb, line 528
def index(*args)
  raise ArgumentError, "wrong number of arguments(#{args.size} for 0-2)" if args.size > 2
  which = (args.size == 2 || SELECTORS.include?(args.last)) ? args.pop : :all
  return to_enum :find_index, which, *args unless block_given? || args.size == 1
  if args.size == 1
    value = args.first
    each_with_index(which) do |e, row_index, col_index|
      return row_index, col_index if e == value
    end
  else
    each_with_index(which) do |e, row_index, col_index|
      return row_index, col_index if yield e
    end
  end
  nil
end
Also aliased as: find_index
inspect() click to toggle source

Overrides Object#inspect

# File lib/matrix.rb, line 1346
def inspect
  if empty?
    "#{self.class}.empty(#{row_count}, #{column_count})"
  else
    "#{self.class}#{@rows.inspect}"
  end
end
inv() click to toggle source
Alias for: inverse
inverse() click to toggle source

Returns the inverse of the matrix.

Matrix[[-1, -1], [0, -1]].inverse
  => -1  1
      0 -1

# File lib/matrix.rb, line 912
def inverse
  Matrix.Raise ErrDimensionMismatch unless square?
  self.class.I(row_count).send(:inverse_from, self)
end
Also aliased as: inv
lower_triangular?() click to toggle source

Returns true is this is a lower triangular matrix.

# File lib/matrix.rb, line 626
def lower_triangular?
  each(:strict_upper).all?(&:zero?)
end
lup() click to toggle source

Returns the LUP decomposition of the matrix; see LUPDecomposition.

a = Matrix[[1, 2], [3, 4]]
l, u, p = a.lup
l.lower_triangular? # => true
u.upper_triangular? # => true
p.permutation?      # => true
l * u == p * a      # => true
a.lup.solve([2, 5]) # => Vector[(1/1), (1/2)]

# File lib/matrix.rb, line 1205
def lup
  LUPDecomposition.new(self)
end
Also aliased as: lup_decomposition
lup_decomposition() click to toggle source
Alias for: lup
map() click to toggle source
Alias for: collect
minor(*param) click to toggle source

Returns a section of the matrix. The parameters are either:

  • start_row, nrows, start_col, ncols; OR

  • row_range, col_range

Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)
  => 9 0 0
     0 5 0

Like Array#[], negative indices count backward from the end of the row or column (-1 is the last element). Returns nil if the starting row or column is greater than #row_count or #column_count respectively.

# File lib/matrix.rb, line 558
def minor(*param)
  case param.size
  when 2
    row_range, col_range = param
    from_row = row_range.first
    from_row += row_count if from_row < 0
    to_row = row_range.end
    to_row += row_count if to_row < 0
    to_row += 1 unless row_range.exclude_end?
    size_row = to_row - from_row

    from_col = col_range.first
    from_col += column_count if from_col < 0
    to_col = col_range.end
    to_col += column_count if to_col < 0
    to_col += 1 unless col_range.exclude_end?
    size_col = to_col - from_col
  when 4
    from_row, size_row, from_col, size_col = param
    return nil if size_row < 0 || size_col < 0
    from_row += row_count if from_row < 0
    from_col += column_count if from_col < 0
  else
    raise ArgumentError, param.inspect
  end

  return nil if from_row > row_count || from_col > column_count || from_row < 0 || from_col < 0
  rows = @rows[from_row, size_row].collect{|row|
    row[from_col, size_col]
  }
  new_matrix rows, [column_count - from_col, size_col].min
end
normal?() click to toggle source

Returns true is this is a normal matrix. Raises an error if matrix is not square.

# File lib/matrix.rb, line 634
def normal?
  Matrix.Raise ErrDimensionMismatch unless square?
  rows.each_with_index do |row_i, i|
    rows.each_with_index do |row_j, j|
      s = 0
      rows.each_with_index do |row_k, k|
        s += row_i[k] * row_j[k].conj - row_k[i].conj * row_k[j]
      end
      return false unless s == 0
    end
  end
  true
end
orthogonal?() click to toggle source

Returns true is this is an orthogonal matrix Raises an error if matrix is not square.

# File lib/matrix.rb, line 652
def orthogonal?
  Matrix.Raise ErrDimensionMismatch unless square?
  rows.each_with_index do |row, i|
    column_count.times do |j|
      s = 0
      row_count.times do |k|
        s += row[k] * rows[k][j]
      end
      return false unless s == (i == j ? 1 : 0)
    end
  end
  true
end
permutation?() click to toggle source

Returns true is this is a permutation matrix Raises an error if matrix is not square.

# File lib/matrix.rb, line 670
def permutation?
  Matrix.Raise ErrDimensionMismatch unless square?
  cols = Array.new(column_count)
  rows.each_with_index do |row, i|
    found = false
    row.each_with_index do |e, j|
      if e == 1
        return false if found || cols[j]
        found = cols[j] = true
      elsif e != 0
        return false
      end
    end
    return false unless found
  end
  true
end
rank() click to toggle source

Returns the rank of the matrix. Beware that using Float values can yield erroneous results because of their lack of precision. Consider using exact types like Rational or BigDecimal instead.

Matrix[[7,6], [3,9]].rank
  => 2

# File lib/matrix.rb, line 1106
def rank
  # We currently use Bareiss' multistep integer-preserving gaussian elimination
  # (see comments on determinant)
  a = to_a
  last_column = column_count - 1
  last_row = row_count - 1
  pivot_row = 0
  previous_pivot = 1
  0.upto(last_column) do |k|
    switch_row = (pivot_row .. last_row).find {|row|
      a[row][k] != 0
    }
    if switch_row
      a[switch_row], a[pivot_row] = a[pivot_row], a[switch_row] unless pivot_row == switch_row
      pivot = a[pivot_row][k]
      (pivot_row+1).upto(last_row) do |i|
         ai = a[i]
         (k+1).upto(last_column) do |j|
           ai[j] =  (pivot * ai[j] - ai[k] * a[pivot_row][j]) / previous_pivot
         end
       end
      pivot_row += 1
      previous_pivot = pivot
    end
  end
  pivot_row
end
rank_e() click to toggle source

deprecated; use #rank

# File lib/matrix.rb, line 1137
def rank_e
  warn "#{caller(1)[0]}: warning: Matrix#rank_e is deprecated; use #rank"
  rank
end
real() click to toggle source

Returns the real part of the matrix.

Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
  => 1+2i  i  0
        1  2  3
Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].real
  =>    1  0  0
        1  2  3

# File lib/matrix.rb, line 1251
def real
  collect(&:real)
end
real?() click to toggle source

Returns true if all entries of the matrix are real.

# File lib/matrix.rb, line 691
def real?
  all?(&:real?)
end
rect() click to toggle source

Returns an array containing matrices corresponding to the real and imaginary parts of the matrix

m.rect == [m.real, m.imag] # ==> true for all matrices m

# File lib/matrix.rb, line 1261
def rect
  [real, imag]
end
Also aliased as: rectangular
rectangular() click to toggle source
Alias for: rect
regular?() click to toggle source

Returns true if this is a regular (i.e. non-singular) matrix.

# File lib/matrix.rb, line 698
def regular?
  not singular?
end
round(ndigits=0) click to toggle source

Returns a matrix with entries rounded to the given precision (see Float#round)

# File lib/matrix.rb, line 1145
def round(ndigits=0)
  map{|e| e.round(ndigits)}
end
row(i) { |e| ... } click to toggle source

Returns row vector number i of the matrix as a Vector (starting at 0 like an array). When a block is given, the elements of that vector are iterated.

# File lib/matrix.rb, line 344
def row(i, &block) # :yield: e
  if block_given?
    @rows.fetch(i){return self}.each(&block)
    self
  else
    Vector.elements(@rows.fetch(i){return nil})
  end
end
row_count() click to toggle source

Returns the number of rows.

# File lib/matrix.rb, line 329
def row_count
  @rows.size
end
Also aliased as: row_size
row_size() click to toggle source
Alias for: row_count
row_vectors() click to toggle source

Returns an array of the row vectors of the matrix. See Vector.

# File lib/matrix.rb, line 1289
def row_vectors
  Array.new(row_count) {|i|
    row(i)
  }
end
singular?() click to toggle source

Returns true is this is a singular matrix.

# File lib/matrix.rb, line 705
def singular?
  determinant == 0
end
square?() click to toggle source

Returns true is this is a square matrix.

# File lib/matrix.rb, line 712
def square?
  column_count == row_count
end
symmetric?() click to toggle source

Returns true is this is a symmetric matrix. Raises an error if matrix is not square.

# File lib/matrix.rb, line 720
def symmetric?
  Matrix.Raise ErrDimensionMismatch unless square?
  each_with_index(:strict_upper) do |e, row, col|
    return false if e != rows[col][row]
  end
  true
end
t() click to toggle source
Alias for: transpose
to_a() click to toggle source

Returns an array of arrays that describe the rows of the matrix.

# File lib/matrix.rb, line 1307
def to_a
  @rows.collect(&:dup)
end
to_s() click to toggle source

Overrides Object#to_s

# File lib/matrix.rb, line 1333
def to_s
  if empty?
    "#{self.class}.empty(#{row_count}, #{column_count})"
  else
    "#{self.class}[" + @rows.collect{|row|
      "[" + row.collect{|e| e.to_s}.join(", ") + "]"
    }.join(", ")+"]"
  end
end
tr() click to toggle source
Alias for: trace
trace() click to toggle source

Returns the trace (sum of diagonal elements) of the matrix.

Matrix[[7,6], [3,9]].trace
  => 16

# File lib/matrix.rb, line 1154
def trace
  Matrix.Raise ErrDimensionMismatch unless square?
  (0...column_count).inject(0) do |tr, i|
    tr + @rows[i][i]
  end
end
Also aliased as: tr
transpose() click to toggle source

Returns the transpose of the matrix.

Matrix[[1,2], [3,4], [5,6]]
  => 1 2
     3 4
     5 6
Matrix[[1,2], [3,4], [5,6]].transpose
  => 1 3 5
     2 4 6

# File lib/matrix.rb, line 1172
def transpose
  return self.class.empty(column_count, 0) if row_count.zero?
  new_matrix @rows.transpose, row_count
end
Also aliased as: t
unitary?() click to toggle source

Returns true is this is a unitary matrix Raises an error if matrix is not square.

# File lib/matrix.rb, line 732
def unitary?
  Matrix.Raise ErrDimensionMismatch unless square?
  rows.each_with_index do |row, i|
    column_count.times do |j|
      s = 0
      row_count.times do |k|
        s += row[k].conj * rows[k][j]
      end
      return false unless s == (i == j ? 1 : 0)
    end
  end
  true
end
upper_triangular?() click to toggle source

Returns true is this is an upper triangular matrix.

# File lib/matrix.rb, line 749
def upper_triangular?
  each(:strict_lower).all?(&:zero?)
end
zero?() click to toggle source

Returns true is this is a matrix with only zero elements

# File lib/matrix.rb, line 756
def zero?
  all?(&:zero?)
end


class Matrix::EigenvalueDecomposition - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Matrix::EigenvalueDecomposition

Eigenvalues and eigenvectors of a real matrix.

Computes the eigenvalues and eigenvectors of a matrix A.

If A is diagonalizable, this provides matrices V and D such that A = V*D*V.inv, where D is the diagonal matrix with entries equal to the eigenvalues and V is formed by the eigenvectors.

If A is symmetric, then V is orthogonal and thus A = V*D*V.t

In Files

  • lib/matrix/eigenvalue_decomposition.rb

Parent

Object

Public Class Methods

new(a) click to toggle source

Constructs the eigenvalue decomposition for a square matrix A

# File lib/matrix/eigenvalue_decomposition.rb, line 18
def initialize(a)
  # @d, @e: Arrays for internal storage of eigenvalues.
  # @v: Array for internal storage of eigenvectors.
  # @h: Array for internal storage of nonsymmetric Hessenberg form.
  raise TypeError, "Expected Matrix but got #{a.class}" unless a.is_a?(Matrix)
  @size = a.row_count
  @d = Array.new(@size, 0)
  @e = Array.new(@size, 0)

  if (@symmetric = a.symmetric?)
    @v = a.to_a
    tridiagonalize
    diagonalize
  else
    @v = Array.new(@size) { Array.new(@size, 0) }
    @h = a.to_a
    @ort = Array.new(@size, 0)
    reduce_to_hessenberg
    hessenberg_to_real_schur
  end
end

Public Instance Methods

d() click to toggle source
Alias for: eigenvalue_matrix
eigenvalue_matrix() click to toggle source

Returns the block diagonal eigenvalue matrix D

# File lib/matrix/eigenvalue_decomposition.rb, line 72
def eigenvalue_matrix
  Matrix.diagonal(*eigenvalues)
end
Also aliased as: d
eigenvalues() click to toggle source

Returns the eigenvalues in an array

# File lib/matrix/eigenvalue_decomposition.rb, line 58
def eigenvalues
  values = @d.dup
  @e.each_with_index{|imag, i| values[i] = Complex(values[i], imag) unless imag == 0}
  values
end
eigenvector_matrix() click to toggle source

Returns the eigenvector matrix V

# File lib/matrix/eigenvalue_decomposition.rb, line 42
def eigenvector_matrix
  Matrix.send :new, build_eigenvectors.transpose
end
Also aliased as: v
eigenvector_matrix_inv() click to toggle source

Returns the inverse of the eigenvector matrix V

# File lib/matrix/eigenvalue_decomposition.rb, line 49
def eigenvector_matrix_inv
  r = Matrix.send :new, build_eigenvectors
  r = r.transpose.inverse unless @symmetric
  r
end
Also aliased as: v_inv
eigenvectors() click to toggle source

Returns an array of the eigenvectors

# File lib/matrix/eigenvalue_decomposition.rb, line 66
def eigenvectors
  build_eigenvectors.map{|ev| Vector.send :new, ev}
end
to_a() click to toggle source
Alias for: to_ary
to_ary() click to toggle source

Returns [#eigenvector_matrix, #eigenvalue_matrix, #eigenvector_matrix_inv]

# File lib/matrix/eigenvalue_decomposition.rb, line 79
def to_ary
  [v, d, v_inv]
end
Also aliased as: to_a
v() click to toggle source
Alias for: eigenvector_matrix
v_inv() click to toggle source
Alias for: eigenvector_matrix_inv


class Matrix::LUPDecomposition - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Matrix::LUPDecomposition

For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n unit lower triangular matrix L, an n-by-n upper triangular matrix U, and a m-by-m permutation matrix P so that L*U = P*A. If m < n, then L is m-by-m and U is m-by-n.

The LUP decomposition with pivoting always exists, even if the matrix is singular, so the constructor will never fail. The primary use of the LU decomposition is in the solution of square systems of simultaneous linear equations. This will fail if singular? returns true.

In Files

  • lib/matrix/lup_decomposition.rb

Parent

Object

Attributes

pivots[R]

Returns the pivoting indices

Public Class Methods

new(a) click to toggle source
# File lib/matrix/lup_decomposition.rb, line 153
def initialize a
  raise TypeError, "Expected Matrix but got #{a.class}" unless a.is_a?(Matrix)
  # Use a "left-looking", dot-product, Crout/Doolittle algorithm.
  @lu = a.to_a
  @row_count = a.row_count
  @column_count = a.column_count
  @pivots = Array.new(@row_count)
  @row_count.times do |i|
     @pivots[i] = i
  end
  @pivot_sign = 1
  lu_col_j = Array.new(@row_count)

  # Outer loop.

  @column_count.times do |j|

    # Make a copy of the j-th column to localize references.

    @row_count.times do |i|
      lu_col_j[i] = @lu[i][j]
    end

    # Apply previous transformations.

    @row_count.times do |i|
      lu_row_i = @lu[i]

      # Most of the time is spent in the following dot product.

      kmax = [i, j].min
      s = 0
      kmax.times do |k|
        s += lu_row_i[k]*lu_col_j[k]
      end

      lu_row_i[j] = lu_col_j[i] -= s
    end

    # Find pivot and exchange if necessary.

    p = j
    (j+1).upto(@row_count-1) do |i|
      if (lu_col_j[i].abs > lu_col_j[p].abs)
        p = i
      end
    end
    if (p != j)
      @column_count.times do |k|
        t = @lu[p][k]; @lu[p][k] = @lu[j][k]; @lu[j][k] = t
      end
      k = @pivots[p]; @pivots[p] = @pivots[j]; @pivots[j] = k
      @pivot_sign = -@pivot_sign
    end

    # Compute multipliers.

    if (j < @row_count && @lu[j][j] != 0)
      (j+1).upto(@row_count-1) do |i|
        @lu[i][j] = @lu[i][j].quo(@lu[j][j])
      end
    end
  end
end

Public Instance Methods

det() click to toggle source

Returns the determinant of A, calculated efficiently from the factorization.

# File lib/matrix/lup_decomposition.rb, line 78
def det
  if (@row_count != @column_count)
    Matrix.Raise Matrix::ErrDimensionMismatch
  end
  d = @pivot_sign
  @column_count.times do |j|
    d *= @lu[j][j]
  end
  d
end
Also aliased as: determinant
determinant() click to toggle source
Alias for: det
l() click to toggle source
# File lib/matrix/lup_decomposition.rb, line 21
def l
  Matrix.build(@row_count, [@column_count, @row_count].min) do |i, j|
    if (i > j)
      @lu[i][j]
    elsif (i == j)
      1
    else
      0
    end
  end
end
p() click to toggle source

Returns the permutation matrix P

# File lib/matrix/lup_decomposition.rb, line 47
def p
  rows = Array.new(@row_count){Array.new(@row_count, 0)}
  @pivots.each_with_index{|p, i| rows[i][p] = 1}
  Matrix.send :new, rows, @row_count
end
singular?() click to toggle source

Returns true if U, and hence A, is singular.

# File lib/matrix/lup_decomposition.rb, line 66
def singular? ()
  @column_count.times do |j|
    if (@lu[j][j] == 0)
      return true
    end
  end
  false
end
solve(b) click to toggle source

Returns m so that A*m = b, or equivalently so that L*U*m = P*b b can be a Matrix or a Vector

# File lib/matrix/lup_decomposition.rb, line 94
def solve b
  if (singular?)
    Matrix.Raise Matrix::ErrNotRegular, "Matrix is singular."
  end
  if b.is_a? Matrix
    if (b.row_count != @row_count)
      Matrix.Raise Matrix::ErrDimensionMismatch
    end

    # Copy right hand side with pivoting
    nx = b.column_count
    m = @pivots.map{|row| b.row(row).to_a}

    # Solve L*Y = P*b
    @column_count.times do |k|
      (k+1).upto(@column_count-1) do |i|
        nx.times do |j|
          m[i][j] -= m[k][j]*@lu[i][k]
        end
      end
    end
    # Solve U*m = Y
    (@column_count-1).downto(0) do |k|
      nx.times do |j|
        m[k][j] = m[k][j].quo(@lu[k][k])
      end
      k.times do |i|
        nx.times do |j|
          m[i][j] -= m[k][j]*@lu[i][k]
        end
      end
    end
    Matrix.send :new, m, nx
  else # same algorithm, specialized for simpler case of a vector
    b = convert_to_array(b)
    if (b.size != @row_count)
      Matrix.Raise Matrix::ErrDimensionMismatch
    end

    # Copy right hand side with pivoting
    m = b.values_at(*@pivots)

    # Solve L*Y = P*b
    @column_count.times do |k|
      (k+1).upto(@column_count-1) do |i|
        m[i] -= m[k]*@lu[i][k]
      end
    end
    # Solve U*m = Y
    (@column_count-1).downto(0) do |k|
      m[k] = m[k].quo(@lu[k][k])
      k.times do |i|
        m[i] -= m[k]*@lu[i][k]
      end
    end
    Vector.elements(m, false)
  end
end
to_a() click to toggle source
Alias for: to_ary
to_ary() click to toggle source

Returns L, U, P in an array

# File lib/matrix/lup_decomposition.rb, line 55
def to_ary
  [l, u, p]
end
Also aliased as: to_a
u() click to toggle source

Returns the upper triangular factor U

# File lib/matrix/lup_decomposition.rb, line 35
def u
  Matrix.build([@column_count, @row_count].min, @column_count) do |i, j|
    if (i <= j)
      @lu[i][j]
    else
      0
    end
  end
end


module Minitest - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Minitest

In Files

Generated by RDoc 3.12.2.

Generated with the Darkfish Rdoc Generator 3.


class MiniTest::Assertion - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class MiniTest::Assertion

Assertion base class

In Files

  • lib/minitest/unit.rb

Parent

Exception


module MiniTest::Assertions - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MiniTest::Assertions

MiniTest Assertions. All assertion methods accept a msg which is printed if the assertion fails.

In Files

  • lib/minitest/unit.rb

Public Class Methods

diff() click to toggle source

Returns the diff command to use in diff. Tries to intelligently figure out what diff to use.

# File lib/minitest/unit.rb, line 88
def self.diff
  @diff = if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ then
            "diff.exe -u"
          else
            if system("gdiff", __FILE__, __FILE__)
              "gdiff -u" # solaris and kin suck
            elsif system("diff", __FILE__, __FILE__)
              "diff -u"
            else
              nil
            end
          end unless defined? @diff

  @diff
end
diff=(o) click to toggle source

Set the diff command to use in diff.

# File lib/minitest/unit.rb, line 107
def self.diff= o
  @diff = o
end

Public Instance Methods

assert(test, msg = nil) click to toggle source

Fails unless test is a true value.

# File lib/minitest/unit.rb, line 194
def assert test, msg = nil
  msg ||= "Failed assertion, no message given."
  self._assertions += 1
  unless test then
    msg = msg.call if Proc === msg
    raise MiniTest::Assertion, msg
  end
  true
end
assert_block(msg = nil) { || ... } click to toggle source

Fails unless the block returns a true value.

NOTE: This method is deprecated, use assert. It will be removed on 2013-01-01.“

# File lib/minitest/unit.rb, line 210
def assert_block msg = nil
  warn "NOTE: MiniTest::Unit::TestCase#assert_block is deprecated, use assert. It will be removed on 2013-01-01. Called from #{caller.first}"
  msg = message(msg) { "Expected block to return true value" }
  assert yield, msg
end
assert_empty(obj, msg = nil) click to toggle source

Fails unless obj is empty.

# File lib/minitest/unit.rb, line 219
def assert_empty obj, msg = nil
  msg = message(msg) { "Expected #{mu_pp(obj)} to be empty" }
  assert_respond_to obj, :empty?
  assert obj.empty?, msg
end
assert_equal(exp, act, msg = nil) click to toggle source

Fails unless exp == act printing the difference between the two, if possible.

If there is no visible difference but the assertion fails, you should suspect that your #== is buggy, or your inspect output is missing crucial details.

For floats use assert_in_delta.

See also: ::diff

# File lib/minitest/unit.rb, line 237
def assert_equal exp, act, msg = nil
  msg = message(msg, "") { diff exp, act }
  assert(exp == act, msg)
end
assert_in_delta(exp, act, delta = 0.001, msg = nil) click to toggle source

For comparing Floats. Fails unless exp and act are within delta of each other.

assert_in_delta Math::PI, (22.0 / 7.0), 0.01
# File lib/minitest/unit.rb, line 248
def assert_in_delta exp, act, delta = 0.001, msg = nil
  n = (exp - act).abs
  msg = message(msg) { "Expected |#{exp} - #{act}| (#{n}) to be < #{delta}"}
  assert delta >= n, msg
end
assert_in_epsilon(a, b, epsilon = 0.001, msg = nil) click to toggle source

For comparing Floats. Fails unless exp and act have a relative error less than epsilon.

# File lib/minitest/unit.rb, line 258
def assert_in_epsilon a, b, epsilon = 0.001, msg = nil
  assert_in_delta a, b, [a.abs, b.abs].min * epsilon, msg
end
assert_includes(collection, obj, msg = nil) click to toggle source

Fails unless collection includes obj.

# File lib/minitest/unit.rb, line 265
def assert_includes collection, obj, msg = nil
  msg = message(msg) {
    "Expected #{mu_pp(collection)} to include #{mu_pp(obj)}"
  }
  assert_respond_to collection, :include?
  assert collection.include?(obj), msg
end
assert_instance_of(cls, obj, msg = nil) click to toggle source

Fails unless obj is an instance of cls.

# File lib/minitest/unit.rb, line 276
def assert_instance_of cls, obj, msg = nil
  msg = message(msg) {
    "Expected #{mu_pp(obj)} to be an instance of #{cls}, not #{obj.class}"
  }

  assert obj.instance_of?(cls), msg
end
assert_kind_of(cls, obj, msg = nil) click to toggle source

Fails unless obj is a kind of cls.

# File lib/minitest/unit.rb, line 287
def assert_kind_of cls, obj, msg = nil # TODO: merge with instance_of
  msg = message(msg) {
    "Expected #{mu_pp(obj)} to be a kind of #{cls}, not #{obj.class}" }

  assert obj.kind_of?(cls), msg
end
assert_match(matcher, obj, msg = nil) click to toggle source

Fails unless matcher =~ obj.

# File lib/minitest/unit.rb, line 297
def assert_match matcher, obj, msg = nil
  msg = message(msg) { "Expected #{mu_pp matcher} to match #{mu_pp obj}" }
  assert_respond_to matcher, :"=~"
  matcher = Regexp.new Regexp.escape matcher if String === matcher
  assert matcher =~ obj, msg
end
assert_nil(obj, msg = nil) click to toggle source

Fails unless obj is nil

# File lib/minitest/unit.rb, line 307
def assert_nil obj, msg = nil
  msg = message(msg) { "Expected #{mu_pp(obj)} to be nil" }
  assert obj.nil?, msg
end
assert_operator(o1, op, o2 = UNDEFINED, msg = nil) click to toggle source

For testing with binary operators.

assert_operator 5, :<=, 4
# File lib/minitest/unit.rb, line 317
def assert_operator o1, op, o2 = UNDEFINED, msg = nil
  return assert_predicate o1, op, msg if UNDEFINED == o2
  msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op} #{mu_pp(o2)}" }
  assert o1.__send__(op, o2), msg
end
assert_output(stdout = nil, stderr = nil) { || ... } click to toggle source

Fails if stdout or stderr do not output the expected results. Pass in nil if you don't care about that streams output. Pass in “” if you require it to be silent. Pass in a regexp if you want to pattern match.

NOTE: this uses capture_io, not capture_subprocess_io.

See also: assert_silent

# File lib/minitest/unit.rb, line 333
def assert_output stdout = nil, stderr = nil
  out, err = capture_io do
    yield
  end

  err_msg = Regexp === stderr ? :assert_match : :assert_equal if stderr
  out_msg = Regexp === stdout ? :assert_match : :assert_equal if stdout

  y = send err_msg, stderr, err, "In stderr" if err_msg
  x = send out_msg, stdout, out, "In stdout" if out_msg

  (!stdout || x) && (!stderr || y)
end
assert_predicate(o1, op, msg = nil) click to toggle source

For testing with predicates.

assert_predicate str, :empty?

This is really meant for specs and is front-ended by #assert_operator:

str.must_be :empty?
# File lib/minitest/unit.rb, line 356
def assert_predicate o1, op, msg = nil
  msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op}" }
  assert o1.__send__(op), msg
end
assert_raises(*exp) { || ... } click to toggle source

Fails unless the block raises one of exp. Returns the exception matched so you can check the message, attributes, etc.

# File lib/minitest/unit.rb, line 365
def assert_raises *exp
  msg = "#{exp.pop}.\n" if String === exp.last

  begin
    yield
  rescue MiniTest::Skip => e
    return e if exp.include? MiniTest::Skip
    raise e
  rescue Exception => e
    expected = exp.any? { |ex|
      if ex.instance_of? Module then
        e.kind_of? ex
      else
        e.instance_of? ex
      end
    }

    assert expected, proc {
      exception_details(e, "#{msg}#{mu_pp(exp)} exception expected, not")
    }

    return e
  end

  exp = exp.first if exp.size == 1

  flunk "#{msg}#{mu_pp(exp)} expected but nothing was raised."
end
assert_respond_to(obj, meth, msg = nil) click to toggle source

Fails unless obj responds to meth.

# File lib/minitest/unit.rb, line 397
def assert_respond_to obj, meth, msg = nil
  msg = message(msg) {
    "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}"
  }
  assert obj.respond_to?(meth), msg
end
assert_same(exp, act, msg = nil) click to toggle source

Fails unless exp and act are equal?

# File lib/minitest/unit.rb, line 407
def assert_same exp, act, msg = nil
  msg = message(msg) {
    data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id]
    "Expected %s (oid=%d) to be the same as %s (oid=%d)" % data
  }
  assert exp.equal?(act), msg
end
assert_send(send_ary, m = nil) click to toggle source

send_ary is a receiver, message and arguments.

Fails unless the call returns a true value TODO: I should prolly remove this from specs

# File lib/minitest/unit.rb, line 421
def assert_send send_ary, m = nil
  recv, msg, *args = send_ary
  m = message(m) {
    "Expected #{mu_pp(recv)}.#{msg}(*#{mu_pp(args)}) to return true" }
  assert recv.__send__(msg, *args), m
end
assert_silent() { || ... } click to toggle source

Fails if the block outputs anything to stderr or stdout.

See also: assert_output

# File lib/minitest/unit.rb, line 433
def assert_silent
  assert_output "", "" do
    yield
  end
end
assert_throws(sym, msg = nil) { || ... } click to toggle source

Fails unless the block throws sym

# File lib/minitest/unit.rb, line 442
def assert_throws sym, msg = nil
  default = "Expected #{mu_pp(sym)} to have been thrown"
  caught = true
  catch(sym) do
    begin
      yield
    rescue ThreadError => e       # wtf?!? 1.8 + threads == suck
      default += ", not \:#{e.message[/uncaught throw \`(\w+?)\'/, 1]}"
    rescue ArgumentError => e     # 1.9 exception
      default += ", not #{e.message.split(/ /).last}"
    rescue NameError => e         # 1.8 exception
      default += ", not #{e.name.inspect}"
    end
    caught = false
  end

  assert caught, message(msg) { default }
end
capture_io() { || ... } click to toggle source

Captures $stdout and $stderr into strings:

out, err = capture_io do
  puts "Some info"
  warn "You did a bad thing"
end

assert_match %r%info%, out
assert_match %r%bad%, err

NOTE: For efficiency, this method uses StringIO and does not capture IO for subprocesses. Use capture_subprocess_io for that.

# File lib/minitest/unit.rb, line 476
def capture_io
  require 'stringio'

  captured_stdout, captured_stderr = StringIO.new, StringIO.new

  synchronize do
    orig_stdout, orig_stderr = $stdout, $stderr
    $stdout, $stderr         = captured_stdout, captured_stderr

    begin
      yield
    ensure
      $stdout = orig_stdout
      $stderr = orig_stderr
    end
  end

  return captured_stdout.string, captured_stderr.string
end
capture_subprocess_io() { || ... } click to toggle source

Captures $stdout and $stderr into strings, using Tempfile to ensure that subprocess IO is captured as well.

out, err = capture_subprocess_io do
  system "echo Some info"
  system "echo You did a bad thing 1>&2"
end

assert_match %r%info%, out
assert_match %r%bad%, err

NOTE: This method is approximately 10x slower than capture_io so only use it when you need to test the output of a subprocess.

# File lib/minitest/unit.rb, line 511
def capture_subprocess_io
  require 'tempfile'

  captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err")

  synchronize do
    orig_stdout, orig_stderr = $stdout.dup, $stderr.dup
    $stdout.reopen captured_stdout
    $stderr.reopen captured_stderr

    begin
      yield

      $stdout.rewind
      $stderr.rewind

      [captured_stdout.read, captured_stderr.read]
    ensure
      captured_stdout.unlink
      captured_stderr.unlink
      $stdout.reopen orig_stdout
      $stderr.reopen orig_stderr
    end
  end
end
diff(exp, act) click to toggle source

Returns a diff between exp and act. If there is no known diff command or if it doesn't make sense to diff the output (single line, short output), then it simply returns a basic comparison between the two.

# File lib/minitest/unit.rb, line 117
def diff exp, act
  require "tempfile"

  expect = mu_pp_for_diff exp
  butwas = mu_pp_for_diff act
  result = nil

  need_to_diff =
    MiniTest::Assertions.diff &&
    (expect.include?("\n")    ||
     butwas.include?("\n")    ||
     expect.size > 30         ||
     butwas.size > 30         ||
     expect == butwas)

  return "Expected: #{mu_pp exp}\n  Actual: #{mu_pp act}" unless
    need_to_diff

  Tempfile.open("expect") do |a|
    a.puts expect
    a.flush

    Tempfile.open("butwas") do |b|
      b.puts butwas
      b.flush

      result = %x#{MiniTest::Assertions.diff} #{a.path} #{b.path}`
      result.sub!(/^\-\-\- .+/, "--- expected")
      result.sub!(/^\+\+\+ .+/, "+++ actual")

      if result.empty? then
        klass = exp.class
        result = [
                  "No visible difference in the #{klass}#inspect output.\n",
                  "You should look at the implementation of #== on ",
                  "#{klass} or its members.\n",
                  expect,
                 ].join
      end
    end
  end

  result
end
exception_details(e, msg) click to toggle source

Returns details for exception e

# File lib/minitest/unit.rb, line 540
def exception_details e, msg
  [
   "#{msg}",
   "Class: <#{e.class}>",
   "Message: <#{e.message.inspect}>",
   "---Backtrace---",
   "#{MiniTest::filter_backtrace(e.backtrace).join("\n")}",
   "---------------",
  ].join "\n"
end
flunk(msg = nil) click to toggle source

Fails with msg

# File lib/minitest/unit.rb, line 554
def flunk msg = nil
  msg ||= "Epic Fail!"
  assert false, msg
end
message(msg = nil, ending = ".", &default) click to toggle source

Returns a proc that will output msg along with the default message.

# File lib/minitest/unit.rb, line 562
def message msg = nil, ending = ".", &default
  proc {
    custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty?
    "#{custom_message}#{default.call}#{ending}"
  }
end
mu_pp(obj) click to toggle source

This returns a human-readable version of obj. By default inspect is called. You can override this to use pretty_print if you want.

# File lib/minitest/unit.rb, line 167
def mu_pp obj
  s = obj.inspect
  s = s.encode Encoding.default_external if defined? Encoding
  s
end
mu_pp_for_diff(obj) click to toggle source

This returns a diff-able human-readable version of obj. This differs from the regular #mu_pp because it expands escaped newlines and makes hex-values generic (like object_ids). This uses #mu_pp to do the first pass and then cleans it up.

# File lib/minitest/unit.rb, line 179
def mu_pp_for_diff obj # TODO: possibly rename
  mu_pp(obj).gsub(/\n/, "\n").gsub(/0x[a-f0-9]+/, '0xXXXXXX')
end
pass(msg = nil) click to toggle source

used for counting assertions

# File lib/minitest/unit.rb, line 572
def pass msg = nil
  assert true
end
refute(test, msg = nil) click to toggle source

Fails if test is a true value

# File lib/minitest/unit.rb, line 579
def refute test, msg = nil
  msg ||= "Failed refutation, no message given"
  not assert(! test, msg)
end
refute_empty(obj, msg = nil) click to toggle source

Fails if obj is empty.

# File lib/minitest/unit.rb, line 587
def refute_empty obj, msg = nil
  msg = message(msg) { "Expected #{mu_pp(obj)} to not be empty" }
  assert_respond_to obj, :empty?
  refute obj.empty?, msg
end
refute_equal(exp, act, msg = nil) click to toggle source

Fails if exp == act.

For floats use refute_in_delta.

# File lib/minitest/unit.rb, line 598
def refute_equal exp, act, msg = nil
  msg = message(msg) {
    "Expected #{mu_pp(act)} to not be equal to #{mu_pp(exp)}"
  }
  refute exp == act, msg
end
refute_in_delta(exp, act, delta = 0.001, msg = nil) click to toggle source

For comparing Floats. Fails if exp is within delta of act.

refute_in_delta Math::PI, (22.0 / 7.0)
# File lib/minitest/unit.rb, line 610
def refute_in_delta exp, act, delta = 0.001, msg = nil
  n = (exp - act).abs
  msg = message(msg) {
    "Expected |#{exp} - #{act}| (#{n}) to not be < #{delta}"
  }
  refute delta > n, msg
end
refute_in_epsilon(a, b, epsilon = 0.001, msg = nil) click to toggle source

For comparing Floats. Fails if exp and act have a relative error less than epsilon.

# File lib/minitest/unit.rb, line 622
def refute_in_epsilon a, b, epsilon = 0.001, msg = nil
  refute_in_delta a, b, a * epsilon, msg
end
refute_includes(collection, obj, msg = nil) click to toggle source

Fails if collection includes obj.

# File lib/minitest/unit.rb, line 629
def refute_includes collection, obj, msg = nil
  msg = message(msg) {
    "Expected #{mu_pp(collection)} to not include #{mu_pp(obj)}"
  }
  assert_respond_to collection, :include?
  refute collection.include?(obj), msg
end
refute_instance_of(cls, obj, msg = nil) click to toggle source

Fails if obj is an instance of cls.

# File lib/minitest/unit.rb, line 640
def refute_instance_of cls, obj, msg = nil
  msg = message(msg) {
    "Expected #{mu_pp(obj)} to not be an instance of #{cls}"
  }
  refute obj.instance_of?(cls), msg
end
refute_kind_of(cls, obj, msg = nil) click to toggle source

Fails if obj is a kind of cls.

# File lib/minitest/unit.rb, line 650
def refute_kind_of cls, obj, msg = nil # TODO: merge with instance_of
  msg = message(msg) { "Expected #{mu_pp(obj)} to not be a kind of #{cls}" }
  refute obj.kind_of?(cls), msg
end
refute_match(matcher, obj, msg = nil) click to toggle source

Fails if matcher =~ obj.

# File lib/minitest/unit.rb, line 658
def refute_match matcher, obj, msg = nil
  msg = message(msg) {"Expected #{mu_pp matcher} to not match #{mu_pp obj}"}
  assert_respond_to matcher, :"=~"
  matcher = Regexp.new Regexp.escape matcher if String === matcher
  refute matcher =~ obj, msg
end
refute_nil(obj, msg = nil) click to toggle source

Fails if obj is nil.

# File lib/minitest/unit.rb, line 668
def refute_nil obj, msg = nil
  msg = message(msg) { "Expected #{mu_pp(obj)} to not be nil" }
  refute obj.nil?, msg
end
refute_operator(o1, op, o2 = UNDEFINED, msg = nil) click to toggle source

Fails if o1 is not op o2. Eg:

refute_operator 1, :>, 2 #=> pass
refute_operator 1, :<, 2 #=> fail

# File lib/minitest/unit.rb, line 679
def refute_operator o1, op, o2 = UNDEFINED, msg = nil
  return refute_predicate o1, op, msg if UNDEFINED == o2
  msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op} #{mu_pp(o2)}"}
  refute o1.__send__(op, o2), msg
end
refute_predicate(o1, op, msg = nil) click to toggle source

For testing with predicates.

refute_predicate str, :empty?

This is really meant for specs and is front-ended by #refute_operator:

str.wont_be :empty?
# File lib/minitest/unit.rb, line 694
def refute_predicate o1, op, msg = nil
  msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op}" }
  refute o1.__send__(op), msg
end
refute_respond_to(obj, meth, msg = nil) click to toggle source

Fails if obj responds to the message meth.

# File lib/minitest/unit.rb, line 702
def refute_respond_to obj, meth, msg = nil
  msg = message(msg) { "Expected #{mu_pp(obj)} to not respond to #{meth}" }

  refute obj.respond_to?(meth), msg
end
refute_same(exp, act, msg = nil) click to toggle source

Fails if exp is the same (by object identity) as act.

# File lib/minitest/unit.rb, line 711
def refute_same exp, act, msg = nil
  msg = message(msg) {
    data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id]
    "Expected %s (oid=%d) to not be the same as %s (oid=%d)" % data
  }
  refute exp.equal?(act), msg
end
skip(msg = nil, bt = caller) click to toggle source

Skips the current test. Gets listed at the end of the run but doesn't cause a failure exit code.

# File lib/minitest/unit.rb, line 723
def skip msg = nil, bt = caller
  msg ||= "Skipped, no message given"
  raise MiniTest::Skip, msg, bt
end
synchronize() { || ... } click to toggle source

Takes a block and wraps it with the runner's shared mutex.

# File lib/minitest/unit.rb, line 731
def synchronize
  Minitest::Unit.runner.synchronize do
    yield
  end
end


module MiniTest::Assertions::UNDEFINED - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MiniTest::Assertions::UNDEFINED

In Files

  • lib/minitest/unit.rb


module MiniTest::Expectations - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MiniTest::Expectations

It's where you hide your “assertions”.

In Files

  • lib/minitest/spec.rb

Public Instance Methods

must_be() click to toggle source

See MiniTest::Assertions#assert_operator

n.must_be :<=, 42

This can also do predicates:

str.must_be :empty?
# File lib/minitest/spec.rb, line 357
infect_an_assertion :assert_operator, :must_be, :reverse
must_be_close_to() click to toggle source

See MiniTest::Assertions#assert_in_delta

n.must_be_close_to m [, delta]
# File lib/minitest/spec.rb, line 288
infect_an_assertion :assert_in_delta, :must_be_close_to
Also aliased as: must_be_within_delta
must_be_empty() click to toggle source

See MiniTest::Assertions#assert_empty.

collection.must_be_empty
# File lib/minitest/spec.rb, line 270
infect_an_assertion :assert_empty, :must_be_empty, :unary
must_be_instance_of() click to toggle source

See MiniTest::Assertions#assert_instance_of

obj.must_be_instance_of klass
# File lib/minitest/spec.rb, line 317
infect_an_assertion :assert_instance_of, :must_be_instance_of
must_be_kind_of() click to toggle source

See MiniTest::Assertions#assert_kind_of

obj.must_be_kind_of mod
# File lib/minitest/spec.rb, line 326
infect_an_assertion :assert_kind_of, :must_be_kind_of
must_be_nil() click to toggle source

See MiniTest::Assertions#assert_nil

obj.must_be_nil
# File lib/minitest/spec.rb, line 344
infect_an_assertion :assert_nil, :must_be_nil, :unary
must_be_same_as() click to toggle source

See MiniTest::Assertions#assert_same

a.must_be_same_as b
# File lib/minitest/spec.rb, line 393
infect_an_assertion :assert_same, :must_be_same_as
must_be_silent() click to toggle source

See MiniTest::Assertions#assert_silent

proc { ... }.must_be_silent
# File lib/minitest/spec.rb, line 412
infect_an_assertion :assert_silent, :must_be_silent
must_be_within_delta() click to toggle source
Alias for: must_be_close_to
must_be_within_epsilon() click to toggle source

See MiniTest::Assertions#assert_in_epsilon

n.must_be_within_epsilon m [, epsilon]
# File lib/minitest/spec.rb, line 299
infect_an_assertion :assert_in_epsilon, :must_be_within_epsilon
must_equal() click to toggle source

See MiniTest::Assertions#assert_equal

a.must_equal b
# File lib/minitest/spec.rb, line 279
infect_an_assertion :assert_equal, :must_equal
must_include() click to toggle source

See MiniTest::Assertions#assert_includes

collection.must_include obj
# File lib/minitest/spec.rb, line 308
infect_an_assertion :assert_includes, :must_include, :reverse
must_match() click to toggle source

See MiniTest::Assertions#assert_match

a.must_match b
# File lib/minitest/spec.rb, line 335
infect_an_assertion :assert_match, :must_match
must_output() click to toggle source

See MiniTest::Assertions#assert_output

proc { ... }.must_output out_or_nil [, err]
# File lib/minitest/spec.rb, line 366
infect_an_assertion :assert_output, :must_output
must_raise() click to toggle source

See MiniTest::Assertions#assert_raises

proc { ... }.must_raise exception
# File lib/minitest/spec.rb, line 375
infect_an_assertion :assert_raises, :must_raise
must_respond_to() click to toggle source

See MiniTest::Assertions#assert_respond_to

obj.must_respond_to msg
# File lib/minitest/spec.rb, line 384
infect_an_assertion :assert_respond_to, :must_respond_to, :reverse
must_send() click to toggle source

See MiniTest::Assertions#assert_send TODO: remove me

a.must_send
# File lib/minitest/spec.rb, line 403
infect_an_assertion :assert_send, :must_send
must_throw() click to toggle source

See MiniTest::Assertions#assert_throws

proc { ... }.must_throw sym
# File lib/minitest/spec.rb, line 421
infect_an_assertion :assert_throws, :must_throw
wont_be() click to toggle source

See MiniTest::Assertions#refute_operator

n.wont_be :<=, 42

This can also do predicates:

str.wont_be :empty?
# File lib/minitest/spec.rb, line 517
infect_an_assertion :refute_operator, :wont_be, :reverse
wont_be_close_to() click to toggle source

See MiniTest::Assertions#refute_in_delta

n.wont_be_close_to m [, delta]
# File lib/minitest/spec.rb, line 448
infect_an_assertion :refute_in_delta, :wont_be_close_to
Also aliased as: wont_be_within_delta
wont_be_empty() click to toggle source

See MiniTest::Assertions#refute_empty

collection.wont_be_empty
# File lib/minitest/spec.rb, line 430
infect_an_assertion :refute_empty, :wont_be_empty, :unary
wont_be_instance_of() click to toggle source

See MiniTest::Assertions#refute_instance_of

obj.wont_be_instance_of klass
# File lib/minitest/spec.rb, line 477
infect_an_assertion :refute_instance_of, :wont_be_instance_of
wont_be_kind_of() click to toggle source

See MiniTest::Assertions#refute_kind_of

obj.wont_be_kind_of mod
# File lib/minitest/spec.rb, line 486
infect_an_assertion :refute_kind_of, :wont_be_kind_of
wont_be_nil() click to toggle source

See MiniTest::Assertions#refute_nil

obj.wont_be_nil
# File lib/minitest/spec.rb, line 504
infect_an_assertion :refute_nil, :wont_be_nil, :unary
wont_be_same_as() click to toggle source

See MiniTest::Assertions#refute_same

a.wont_be_same_as b
# File lib/minitest/spec.rb, line 535
infect_an_assertion :refute_same, :wont_be_same_as
wont_be_within_delta() click to toggle source
Alias for: wont_be_close_to
wont_be_within_epsilon() click to toggle source

See MiniTest::Assertions#refute_in_epsilon

n.wont_be_within_epsilon m [, epsilon]
# File lib/minitest/spec.rb, line 459
infect_an_assertion :refute_in_epsilon, :wont_be_within_epsilon
wont_equal() click to toggle source

See MiniTest::Assertions#refute_equal

a.wont_equal b
# File lib/minitest/spec.rb, line 439
infect_an_assertion :refute_equal, :wont_equal
wont_include() click to toggle source

See MiniTest::Assertions#refute_includes

collection.wont_include obj
# File lib/minitest/spec.rb, line 468
infect_an_assertion :refute_includes, :wont_include, :reverse
wont_match() click to toggle source

See MiniTest::Assertions#refute_match

a.wont_match b
# File lib/minitest/spec.rb, line 495
infect_an_assertion :refute_match, :wont_match
wont_respond_to() click to toggle source

See MiniTest::Assertions#refute_respond_to

obj.wont_respond_to msg
# File lib/minitest/spec.rb, line 526
infect_an_assertion :refute_respond_to, :wont_respond_to, :reverse


class MiniTest::Mock - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class MiniTest::Mock

All mock objects are an instance of Mock

In Files

  • lib/minitest/mock.rb

Parent

Object

Public Instance Methods

expect(name, retval, args=[], &blk) click to toggle source

Expect that method name is called, optionally with args or a blk, and returns retval.

@mock.expect(:meaning_of_life, 42)
@mock.meaning_of_life # => 42

@mock.expect(:do_something_with, true, [some_obj, true])
@mock.do_something_with(some_obj, true) # => true

@mock.expect(:do_something_else, true) do |a1, a2|
  a1 == "buggs" && a2 == :bunny
end

args is compared to the expected args using case equality (ie, the '===' operator), allowing for less specific expectations.

@mock.expect(:uses_any_string, true, [String])
@mock.uses_any_string("foo") # => true
@mock.verify  # => true

@mock.expect(:uses_one_string, true, ["foo"]
@mock.uses_one_string("bar") # => true
@mock.verify  # => raises MockExpectationError

# File lib/minitest/mock.rb, line 57
def expect(name, retval, args=[], &blk)
  if block_given?
    raise ArgumentError, "args ignored when block given" unless args.empty?
    @expected_calls[name] << { :retval => retval, :block => blk }
  else
    raise ArgumentError, "args must be an array" unless Array === args
    @expected_calls[name] << { :retval => retval, :args => args }
  end
  self
end
verify() click to toggle source

Verify that all methods were called as expected. Raises MockExpectationError if the mock object was not called as expected.

# File lib/minitest/mock.rb, line 82
def verify
  @expected_calls.each do |name, calls|
    calls.each do |expected|
      msg1 = "expected #{__call name, expected}"
      msg2 = "#{msg1}, got [#{__call name, @actual_calls[name]}]"

      raise MockExpectationError, msg2 if
        @actual_calls.has_key?(name) and
        not @actual_calls[name].include?(expected)

      raise MockExpectationError, msg1 unless
        @actual_calls.has_key?(name) and
        @actual_calls[name].include?(expected)
    end
  end
  true
end


class MiniTest::Skip - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class MiniTest::Skip

Assertion raised when skipping a test

In Files

  • lib/minitest/unit.rb

Parent

MiniTest::Assertion


class MiniTest::Spec - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class MiniTest::Spec

MiniTest::Spec – The faster, better, less-magical spec framework!

For a list of expectations, see MiniTest::Expectations.

In Files

  • lib/minitest/benchmark.rb
  • lib/minitest/spec.rb

Parent

MiniTest::Unit::TestCase

Constants

TYPES

Contains pairs of matchers and Spec classes to be used to calculate the superclass of a top-level describe. This allows for automatically customizable spec types.

See: ::register_spec_type and ::spec_type

Public Class Methods

after(type = nil, &block) click to toggle source

Define an 'after' action. Inherits the way normal methods should.

NOTE: type is ignored and is only there to make porting easier.

Equivalent to MiniTest::Unit::TestCase#teardown.

# File lib/minitest/spec.rb, line 178
def self.after type = nil, &block
  define_method :teardown do
    self.instance_eval(&block)
    super()
  end
end
before(type = nil, &block) click to toggle source

Define a 'before' action. Inherits the way normal methods should.

NOTE: type is ignored and is only there to make porting easier.

Equivalent to MiniTest::Unit::TestCase#setup.

# File lib/minitest/spec.rb, line 164
def self.before type = nil, &block
  define_method :setup do
    super()
    self.instance_eval(&block)
  end
end
bench(name, &block) click to toggle source

This is used to define a new benchmark method. You usually don't use this directly and is intended for those needing to write new performance curve fits (eg: you need a specific polynomial fit).

See ::bench_performance_linear for an example of how to use this.

# File lib/minitest/benchmark.rb, line 315
def self.bench name, &block
  define_method "bench_#{name.gsub(/\W+/, '_')}", &block
end
bench_performance_constant(name, threshold = 0.99, &work) click to toggle source

Create a benchmark that verifies that the performance is constant.

describe "my class" do
  bench_performance_constant "zoom_algorithm!" do |n|
    @obj.zoom_algorithm!(n)
  end
end

# File lib/minitest/benchmark.rb, line 359
def self.bench_performance_constant name, threshold = 0.99, &work
  bench name do
    assert_performance_constant threshold, &work
  end
end
bench_performance_exponential(name, threshold = 0.99, &work) click to toggle source

Create a benchmark that verifies that the performance is exponential.

describe "my class" do
  bench_performance_exponential "algorithm" do |n|
    @obj.algorithm(n)
  end
end

# File lib/minitest/benchmark.rb, line 374
def self.bench_performance_exponential name, threshold = 0.99, &work
  bench name do
    assert_performance_exponential threshold, &work
  end
end
bench_performance_linear(name, threshold = 0.99, &work) click to toggle source

Create a benchmark that verifies that the performance is linear.

describe "my class" do
  bench_performance_linear "fast_algorithm", 0.9999 do |n|
    @obj.fast_algorithm(n)
  end
end

# File lib/minitest/benchmark.rb, line 344
def self.bench_performance_linear name, threshold = 0.99, &work
  bench name do
    assert_performance_linear threshold, &work
  end
end
bench_range(&block) click to toggle source

Specifies the ranges used for benchmarking for that class.

bench_range do
  bench_exp(2, 16, 2)
end

See MiniTest::Unit::TestCase.bench_range for more details.

# File lib/minitest/benchmark.rb, line 328
def self.bench_range &block
  return super unless block

  meta = (class << self; self; end)
  meta.send :define_method, "bench_range", &block
end
children() click to toggle source

Returns the children of this spec.

# File lib/minitest/spec.rb, line 147
def self.children
  @children ||= []
end
it(desc = "anonymous", &block) click to toggle source

Define an expectation with name desc. Name gets morphed to a proper test method name. For some freakish reason, people who write specs don't like class inheritence, so this goes way out of its way to make sure that expectations aren't inherited.

This is also aliased to specify and doesn't require a desc arg.

Hint: If you do want inheritence, use minitest/unit. You can mix and match between assertions and expectations as much as you want.

# File lib/minitest/spec.rb, line 196
def self.it desc = "anonymous", &block
  block ||= proc { skip "(no tests defined)" }

  @specs ||= 0
  @specs += 1

  name = "test_%04d_%s" % [ @specs, desc ]

  define_method name, &block

  self.children.each do |mod|
    mod.send :undef_method, name if mod.public_method_defined? name
  end

  name
end
let(name, &block) click to toggle source

Essentially, define an accessor for name with block.

Why use let instead of def? I honestly don't know.

# File lib/minitest/spec.rb, line 218
def self.let name, &block
  define_method name do
    @_memoized ||= {}
    @_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) }
  end
end
register_spec_type(*args, &block) click to toggle source

Register a new type of spec that matches the spec's description. This method can take either a Regexp and a spec class or a spec class and a block that takes the description and returns true if it matches.

Eg:

register_spec_type(/Controller$/, MiniTest::Spec::Rails)

or:

register_spec_type(MiniTest::Spec::RailsModel) do |desc|
  desc.superclass == ActiveRecord::Base
end

# File lib/minitest/spec.rb, line 115
def self.register_spec_type(*args, &block)
  if block then
    matcher, klass = block, args.first
  else
    matcher, klass = *args
  end
  TYPES.unshift [matcher, klass]
end
spec_type(desc) click to toggle source

Figure out the spec class to use based on a spec's description. Eg:

spec_type("BlahController") # => MiniTest::Spec::Rails

# File lib/minitest/spec.rb, line 129
def self.spec_type desc
  TYPES.find { |matcher, klass|
    if matcher.respond_to? :call then
      matcher.call desc
    else
      matcher === desc.to_s
    end
  }.last
end
subject(&block) click to toggle source

Another lazy man's accessor generator. Made even more lazy by setting the name for you to subject.

# File lib/minitest/spec.rb, line 229
def self.subject &block
  let :subject, &block
end


module Minitest::Unit - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Minitest::Unit

In Files

Generated by RDoc 3.12.2.

Generated with the Darkfish Rdoc Generator 3.


module MiniTest::Unit::Deprecated - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MiniTest::Unit::Deprecated

In Files

  • lib/minitest/unit.rb


module MiniTest::Unit::Deprecated::Hooks - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MiniTest::Unit::Deprecated::Hooks

This entire module is deprecated and slated for removal on 2013-01-01.

In Files

  • lib/minitest/unit.rb


module MiniTest::Unit::Deprecated::HooksCM - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MiniTest::Unit::Deprecated::HooksCM

This entire module is deprecated and slated for removal on 2013-01-01.

In Files

  • lib/minitest/unit.rb

Public Instance Methods

add_setup_hook(arg=nil, &block) click to toggle source

Adds a block of code that will be executed before every TestCase is run.

NOTE: This method is deprecated, use before/after_setup. It will be removed on 2013-01-01.

# File lib/minitest/unit.rb, line 1221
def add_setup_hook arg=nil, &block
  warn "NOTE: MiniTest::Unit::TestCase.add_setup_hook is deprecated, use before/after_setup via a module (and call super!). It will be removed on 2013-01-01. Called from #{caller.first}"
  hook = arg || block
  @setup_hooks << hook
end
add_teardown_hook(arg=nil, &block) click to toggle source

Adds a block of code that will be executed after every TestCase is run.

NOTE: This method is deprecated, use before/after_teardown. It will be removed on 2013-01-01.

# File lib/minitest/unit.rb, line 1242
def add_teardown_hook arg=nil, &block
  warn "NOTE: MiniTest::Unit::TestCase#add_teardown_hook is deprecated, use before/after_teardown. It will be removed on 2013-01-01. Called from #{caller.first}"
  hook = arg || block
  @teardown_hooks << hook
end


module MiniTest::Unit::Guard - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MiniTest::Unit::Guard

Provides a simple set of guards that you can use in your tests to skip execution if it is not applicable. These methods are mixed into TestCase as both instance and class methods so you can use them inside or outside of the test methods.

def test_something_for_mri
  skip "bug 1234"  if jruby?
  # ...
end

if windows? then
  # ... lots of test methods ...
end

In Files

  • lib/minitest/unit.rb

Public Instance Methods

jruby?(platform = RUBY_PLATFORM) click to toggle source

Is this running on jruby?

# File lib/minitest/unit.rb, line 1090
def jruby? platform = RUBY_PLATFORM
  "java" == platform
end
mri?(platform = RUBY_DESCRIPTION) click to toggle source

Is this running on mri?

# File lib/minitest/unit.rb, line 1097
def mri? platform = RUBY_DESCRIPTION
  /^ruby/ =~ platform
end
rubinius?(platform = defined?(RUBY_ENGINE) && RUBY_ENGINE) click to toggle source

Is this running on rubinius?

# File lib/minitest/unit.rb, line 1104
def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
  "rbx" == platform
end
windows?(platform = RUBY_PLATFORM) click to toggle source

Is this running on windows?

# File lib/minitest/unit.rb, line 1111
def windows? platform = RUBY_PLATFORM
  /mswin|mingw/ =~ platform
end


module MiniTest::Unit::LifecycleHooks - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MiniTest::Unit::LifecycleHooks

Provides before/after hooks for setup and teardown. These are meant for library writers, NOT for regular test authors. See before_setup for an example.

In Files

  • lib/minitest/unit.rb

Public Instance Methods

after_setup() click to toggle source

Runs before every test, after setup. This hook is meant for libraries to extend minitest. It is not meant to be used by test developers.

See before_setup for an example.

# File lib/minitest/unit.rb, line 1129
def after_setup; end
after_teardown() click to toggle source

Runs after every test, after teardown. This hook is meant for libraries to extend minitest. It is not meant to be used by test developers.

See before_setup for an example.

# File lib/minitest/unit.rb, line 1182
def after_teardown; end
before_setup() click to toggle source

Runs before every test, before setup. This hook is meant for libraries to extend minitest. It is not meant to be used by test developers.

As a simplistic example:

module MyMinitestPlugin
  def before_setup
    super
    # ... stuff to do before setup is run
  end

  def after_setup
    # ... stuff to do after setup is run
    super
  end

  def before_teardown
    super
    # ... stuff to do before teardown is run
  end

  def after_teardown
    # ... stuff to do after teardown is run
    super
  end
end

class MiniTest::Unit::TestCase
  include MyMinitestPlugin
end

# File lib/minitest/unit.rb, line 1164
def before_setup; end
before_teardown() click to toggle source

Runs after every test, before teardown. This hook is meant for libraries to extend minitest. It is not meant to be used by test developers.

See before_setup for an example.

# File lib/minitest/unit.rb, line 1173
def before_teardown; end


class MiniTest::Unit::TestCase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class MiniTest::Unit::TestCase

Subclass TestCase to create your own tests. Typically you'll want a TestCase subclass per implementation class.

See MiniTest::Assertions

In Files

  • lib/minitest/benchmark.rb
  • lib/minitest/unit.rb
  • lib/test/unit.rb

Parent

Object

Included Modules

  • MiniTest::Unit::LifecycleHooks
  • MiniTest::Unit::Deprecated::Hooks
  • MiniTest::Unit::Guard
  • MiniTest::Assertions

Constants

RUN_TEST_TRACE

Public Class Methods

bench_exp(min, max, base = 10) click to toggle source

Returns a set of ranges stepped exponentially from min to max by powers of base. Eg:

bench_exp(2, 16, 2) # => [2, 4, 8, 16]

# File lib/minitest/benchmark.rb, line 26
def self.bench_exp min, max, base = 10
  min = (Math.log10(min) / Math.log10(base)).to_i
  max = (Math.log10(max) / Math.log10(base)).to_i

  (min..max).map { |m| base ** m }.to_a
end
bench_linear(min, max, step = 10) click to toggle source

Returns a set of ranges stepped linearly from min to max by step. Eg:

bench_linear(20, 40, 10) # => [20, 30, 40]

# File lib/minitest/benchmark.rb, line 39
def self.bench_linear min, max, step = 10
  (min..max).step(step).to_a
rescue LocalJumpError # 1.8.6
  r = []; (min..max).step(step) { |n| r << n }; r
end
bench_range() click to toggle source

Specifies the ranges used for benchmarking for that class. Defaults to exponential growth from 1 to 10k by powers of 10. Override if you need different ranges for your benchmarks.

See also: ::bench_exp and ::bench_linear.

# File lib/minitest/benchmark.rb, line 67
def self.bench_range
  bench_exp 1, 10_000
end
benchmark_suites() click to toggle source

Returns all test suites that have benchmark methods.

# File lib/minitest/benchmark.rb, line 56
def self.benchmark_suites
  TestCase.test_suites.reject { |s| s.benchmark_methods.empty? }
end
i_suck_and_my_tests_are_order_dependent!() click to toggle source

Call this at the top of your tests when you absolutely positively need to have ordered tests. In doing so, you're admitting that you suck and your tests are weak.

# File lib/minitest/unit.rb, line 1367
def self.i_suck_and_my_tests_are_order_dependent!
  class << self
    undef_method :test_order if method_defined? :test_order
    define_method :test_order do :alpha end
  end
end
make_my_diffs_pretty!() click to toggle source

Make diffs for this TestCase use pretty_inspect so that diff in assert_equal can be more details. NOTE: this is much slower than the regular inspect but much more usable for complex objects.

# File lib/minitest/unit.rb, line 1380
def self.make_my_diffs_pretty!
  require 'pp'

  define_method :mu_pp do |o|
    o.pretty_inspect
  end
end
parallelize_me!() click to toggle source

Call this at the top of your tests when you want to run your tests in parallel. In doing so, you're admitting that you rule and your tests are awesome.

# File lib/minitest/unit.rb, line 1393
def self.parallelize_me!
  class << self
    undef_method :test_order if method_defined? :test_order
    define_method :test_order do :parallel end
  end
end

Public Instance Methods

assert_performance(validation, &work) click to toggle source

Runs the given work, gathering the times of each run. Range and times are then passed to a given validation proc. Outputs the benchmark name and times in tab-separated format, making it easy to paste into a spreadsheet for graphing or further analysis.

Ranges are specified by ::bench_range.

Eg:

def bench_algorithm
  validation = proc { |x, y| ... }
  assert_performance validation do |n|
    @obj.algorithm(n)
  end
end

# File lib/minitest/benchmark.rb, line 89
def assert_performance validation, &work
  range = self.class.bench_range

  io.print "#{__name__}"

  times = []

  range.each do |x|
    GC.start
    t0 = Time.now
    instance_exec(x, &work)
    t = Time.now - t0

    io.print "\t%9.6f" % t
    times << t
  end
  io.puts

  validation[range, times]
end
assert_performance_constant(threshold = 0.99, &work) click to toggle source

Runs the given work and asserts that the times gathered fit to match a constant rate (eg, linear slope == 0) within a given threshold. Note: because we're testing for a slope of 0, R^2 is not a good determining factor for the fit, so the threshold is applied against the slope itself. As such, you probably want to tighten it from the default.

See www.graphpad.com/curvefit/goodness_of_fit.htm for more details.

Fit is calculated by fit_linear.

Ranges are specified by ::bench_range.

Eg:

def bench_algorithm
  assert_performance_constant 0.9999 do |n|
    @obj.algorithm(n)
  end
end

# File lib/minitest/benchmark.rb, line 133
def assert_performance_constant threshold = 0.99, &work
  validation = proc do |range, times|
    a, b, rr = fit_linear range, times
    assert_in_delta 0, b, 1 - threshold
    [a, b, rr]
  end

  assert_performance validation, &work
end
assert_performance_exponential(threshold = 0.99, &work) click to toggle source

Runs the given work and asserts that the times gathered fit to match a exponential curve within a given error threshold.

Fit is calculated by fit_exponential.

Ranges are specified by ::bench_range.

Eg:

def bench_algorithm
  assert_performance_exponential 0.9999 do |n|
    @obj.algorithm(n)
  end
end

# File lib/minitest/benchmark.rb, line 159
def assert_performance_exponential threshold = 0.99, &work
  assert_performance validation_for_fit(:exponential, threshold), &work
end
assert_performance_linear(threshold = 0.99, &work) click to toggle source

Runs the given work and asserts that the times gathered fit to match a straight line within a given error threshold.

Fit is calculated by fit_linear.

Ranges are specified by ::bench_range.

Eg:

def bench_algorithm
  assert_performance_linear 0.9999 do |n|
    @obj.algorithm(n)
  end
end

# File lib/minitest/benchmark.rb, line 179
def assert_performance_linear threshold = 0.99, &work
  assert_performance validation_for_fit(:linear, threshold), &work
end
assert_performance_power(threshold = 0.99, &work) click to toggle source

Runs the given work and asserts that the times gathered curve fit to match a power curve within a given error threshold.

Fit is calculated by fit_power.

Ranges are specified by ::bench_range.

Eg:

def bench_algorithm
  assert_performance_power 0.9999 do |x|
    @obj.algorithm
  end
end

# File lib/minitest/benchmark.rb, line 199
def assert_performance_power threshold = 0.99, &work
  assert_performance validation_for_fit(:power, threshold), &work
end
fit_error(xys) { |x| ... } click to toggle source

Takes an array of x/y pairs and calculates the general R^2 value.

See: en.wikipedia.org/wiki/Coefficient_of_determination

# File lib/minitest/benchmark.rb, line 208
def fit_error xys
  y_bar  = sigma(xys) { |x, y| y } / xys.size.to_f
  ss_tot = sigma(xys) { |x, y| (y    - y_bar) ** 2 }
  ss_err = sigma(xys) { |x, y| (yield(x) - y) ** 2 }

  1 - (ss_err / ss_tot)
end
fit_exponential(xs, ys) click to toggle source

To fit a functional form: y = ae^(bx).

Takes x and y values and returns [a, b, r^2].

See: mathworld.wolfram.com/LeastSquaresFittingExponential.html

# File lib/minitest/benchmark.rb, line 223
def fit_exponential xs, ys
  n     = xs.size
  xys   = xs.zip(ys)
  sxlny = sigma(xys) { |x,y| x * Math.log(y) }
  slny  = sigma(xys) { |x,y| Math.log(y)     }
  sx2   = sigma(xys) { |x,y| x * x           }
  sx    = sigma xs

  c = n * sx2 - sx ** 2
  a = (slny * sx2 - sx * sxlny) / c
  b = ( n * sxlny - sx * slny ) / c

  return Math.exp(a), b, fit_error(xys) { |x| Math.exp(a + b * x) }
end
fit_linear(xs, ys) click to toggle source

Fits the functional form: a + bx.

Takes x and y values and returns [a, b, r^2].

See: mathworld.wolfram.com/LeastSquaresFitting.html

# File lib/minitest/benchmark.rb, line 245
def fit_linear xs, ys
  n   = xs.size
  xys = xs.zip(ys)
  sx  = sigma xs
  sy  = sigma ys
  sx2 = sigma(xs)  { |x|   x ** 2 }
  sxy = sigma(xys) { |x,y| x * y  }

  c = n * sx2 - sx**2
  a = (sy * sx2 - sx * sxy) / c
  b = ( n * sxy - sx * sy ) / c

  return a, b, fit_error(xys) { |x| a + b * x }
end
fit_power(xs, ys) click to toggle source

To fit a functional form: y = ax^b.

Takes x and y values and returns [a, b, r^2].

See: mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html

# File lib/minitest/benchmark.rb, line 267
def fit_power xs, ys
  n       = xs.size
  xys     = xs.zip(ys)
  slnxlny = sigma(xys) { |x, y| Math.log(x) * Math.log(y) }
  slnx    = sigma(xs)  { |x   | Math.log(x)               }
  slny    = sigma(ys)  { |   y| Math.log(y)               }
  slnx2   = sigma(xs)  { |x   | Math.log(x) ** 2          }

  b = (n * slnxlny - slnx * slny) / (n * slnx2 - slnx ** 2);
  a = (slny - b * slnx) / n

  return Math.exp(a), b, fit_error(xys) { |x| (Math.exp(a) * (x ** b)) }
end
io() click to toggle source

Return the output IO object

# File lib/minitest/unit.rb, line 1344
def io
  @__io__ = true
  MiniTest::Unit.output
end
io?() click to toggle source

Have we hooked up the IO yet?

# File lib/minitest/unit.rb, line 1352
def io?
  @__io__
end
passed?() click to toggle source

Returns true if the test passed.

# File lib/minitest/unit.rb, line 1434
def passed?
  @passed
end
run(runner) click to toggle source

Runs the tests reporting the status to runner

# File lib/minitest/unit.rb, line 1281
def run runner
  trap "INFO" do
    runner.report.each_with_index do |msg, i|
      warn "\n%3d) %s" % [i + 1, msg]
    end
    warn ''
    time = runner.start_time ? Time.now - runner.start_time : 0
    warn "Current Test: %s#%s %.2fs" % [self.class, self.__name__, time]
    runner.status $stderr
  end if SUPPORTS_INFO_SIGNAL

  start_time = Time.now

  result = ""
  begin
    @passed = nil
    self.before_setup
    self.setup
    self.after_setup
    self.run_test self.__name__
    result = "." unless io?
    time = Time.now - start_time
    runner.record self.class, self.__name__, self._assertions, time, nil
    @passed = true
  rescue *PASSTHROUGH_EXCEPTIONS
    raise
  rescue Exception => e
    @passed = false
    time = Time.now - start_time
    runner.record self.class, self.__name__, self._assertions, time, e
    result = runner.puke self.class, self.__name__, e
  ensure
    %w{ before_teardown teardown after_teardown }.each do |hook|
      begin
        self.send hook
      rescue *PASSTHROUGH_EXCEPTIONS
        raise
      rescue Exception => e
        @passed = false
        result = runner.puke self.class, self.__name__, e
      end
    end
    trap 'INFO', 'DEFAULT' if SUPPORTS_INFO_SIGNAL
  end
  result
end
run_test(name) click to toggle source
# File lib/test/unit.rb, line 856
def run_test(name)
  progname, $0 = $0, "#{$0}: #{self.class}##{name}"
  self.__send__(name)
ensure
  $@.delete(RUN_TEST_TRACE) if $@
  $0 = progname
end
setup() click to toggle source

Runs before every test. Use this to set up before each test run.

# File lib/minitest/unit.rb, line 1442
def setup; end
sigma(enum, &block) click to toggle source

Enumerates over enum mapping block if given, returning the sum of the result. Eg:

sigma([1, 2, 3])                # => 1 + 2 + 3 => 7
sigma([1, 2, 3]) { |n| n ** 2 } # => 1 + 4 + 9 => 14

# File lib/minitest/benchmark.rb, line 288
def sigma enum, &block
  enum = enum.map(&block) if block
  enum.inject { |sum, n| sum + n }
end
teardown() click to toggle source

Runs after every test. Use this to clean up after each test run.

# File lib/minitest/unit.rb, line 1448
def teardown; end
validation_for_fit(msg, threshold) click to toggle source

Returns a proc that calls the specified fit method and asserts that the error is within a tolerable threshold.

# File lib/minitest/benchmark.rb, line 297
def validation_for_fit msg, threshold
  proc do |range, times|
    a, b, rr = send "fit_#{msg}", range, times
    assert_operator rr, :>=, threshold
    [a, b, rr]
  end
end


class Module - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Module

Core extension library

Rake extensions to Module.

In Files

  • lib/minitest/spec.rb
  • lib/rake/ext/core.rb
  • lib/rake/ext/module.rb
  • ext/psych/lib/psych/core_ext.rb

Parent

Object

Public Instance Methods

const_missing(const_name) click to toggle source

Check for deprecated uses of top level (i.e. in Object) uses of Rake class names. If someone tries to reference the constant name, display a warning and return the proper object. Using the –classic-namespace command line option will define these constants in Object and avoid this handler.

# File lib/rake/ext/module.rb, line 21
def const_missing(const_name)
  case const_name
  when :Task
    Rake.application.const_warning(const_name)
    Rake::Task
  when :FileTask
    Rake.application.const_warning(const_name)
    Rake::FileTask
  when :FileCreationTask
    Rake.application.const_warning(const_name)
    Rake::FileCreationTask
  when :RakeApp
    Rake.application.const_warning(const_name)
    Rake::Application
  else
    rake_original_const_missing(const_name)
  end
end
Also aliased as: rake_original_const_missing
psych_yaml_as(url) click to toggle source
# File ext/psych/lib/psych/core_ext.rb, line 21
def psych_yaml_as url
  return if caller[0].end_with?('rubytypes.rb')
  if $VERBOSE
    warn "#{caller[0]}: yaml_as is deprecated, please use yaml_tag"
  end
  Psych.add_tag(url, self)
end
Also aliased as: yaml_as
rake_extension(method) { || ... } click to toggle source

Check for an existing method in the current class before extending. IF the method already exists, then a warning is printed and the extension is not added. Otherwise the block is yielded and any definitions in the block will take effect.

Usage:

class String
  rake_extension("xyz") do
    def xyz
      ...
    end
  end
end

# File lib/rake/ext/core.rb, line 20
def rake_extension(method)
  if method_defined?(method)
    $stderr.puts "WARNING: Possible conflict with Rake extension: #{self}##{method} already exists"
  else
    yield
  end
end
rake_original_const_missing(const_name) click to toggle source

Rename the original handler to make it available.

Alias for: const_missing
yaml_as(url) click to toggle source
Alias for: psych_yaml_as


class Monitor - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Monitor

Use the Monitor class when you want to have a lock object for blocks with mutual exclusion.

require 'monitor'

lock = Monitor.new
lock.synchronize do
  # exclusive access
end

In Files

  • lib/monitor.rb

Parent

Object

Included Modules

  • MonitorMixin


module MonitorMixin - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module MonitorMixin

In concurrent programming, a monitor is an object or module intended to be used safely by more than one thread. The defining characteristic of a monitor is that its methods are executed with mutual exclusion. That is, at each point in time, at most one thread may be executing any of its methods. This mutual exclusion greatly simplifies reasoning about the implementation of monitors compared to reasoning about parallel code that updates a data structure.

You can read more about the general principles on the Wikipedia page for Monitors

Examples

Simple object.extend

require 'monitor.rb'

buf = []
buf.extend(MonitorMixin)
empty_cond = buf.new_cond

# consumer
Thread.start do
  loop do
    buf.synchronize do
      empty_cond.wait_while { buf.empty? }
      print buf.shift
    end
  end
end

# producer
while line = ARGF.gets
  buf.synchronize do
    buf.push(line)
    empty_cond.signal
  end
end

The consumer thread waits for the producer thread to push a line to buf while buf.empty?. The producer thread (main thread) reads a line from ARGF and pushes it into buf then calls empty_cond.signal to notify the consumer thread of new data.

Simple Class include

require 'monitor'

class SynchronizedArray < Array

  include MonitorMixin

  def initialize(*args)
    super(*args)
  end

  alias :old_shift :shift
  alias :old_unshift :unshift

  def shift(n=1)
    self.synchronize do
      self.old_shift(n)
    end
  end

  def unshift(item)
    self.synchronize do
      self.old_unshift(item)
    end
  end

  # other methods ...
end

SynchronizedArray implements an Array with synchronized access to items. This Class is implemented as subclass of Array which includes the MonitorMixin module.

In Files

  • lib/monitor.rb

Public Class Methods

extend_object(obj) click to toggle source
# File lib/monitor.rb, line 159
def self.extend_object(obj)
  super(obj)
  obj.__send__(:mon_initialize)
end
new(*args) click to toggle source

Use extend MonitorMixin or include MonitorMixin instead of this constructor. Have look at the examples above to understand how to use this module.

# File lib/monitor.rb, line 231
def initialize(*args)
  super
  mon_initialize
end

Public Instance Methods

mon_enter() click to toggle source

Enters exclusive section.

# File lib/monitor.rb, line 183
def mon_enter
  if @mon_owner != Thread.current
    @mon_mutex.lock
    @mon_owner = Thread.current
  end
  @mon_count += 1
end
mon_exit() click to toggle source

Leaves exclusive section.

# File lib/monitor.rb, line 194
def mon_exit
  mon_check_owner
  @mon_count -=1
  if @mon_count == 0
    @mon_owner = nil
    @mon_mutex.unlock
  end
end
mon_synchronize() { || ... } click to toggle source

Enters exclusive section and executes the block. Leaves the exclusive section automatically when the block exits. See example under MonitorMixin.

# File lib/monitor.rb, line 208
def mon_synchronize
  mon_enter
  begin
    yield
  ensure
    mon_exit
  end
end
Also aliased as: synchronize
mon_try_enter() click to toggle source

Attempts to enter exclusive section. Returns false if lock fails.

# File lib/monitor.rb, line 167
def mon_try_enter
  if @mon_owner != Thread.current
    unless @mon_mutex.try_lock
      return false
    end
    @mon_owner = Thread.current
  end
  @mon_count += 1
  return true
end
Also aliased as: try_mon_enter
new_cond() click to toggle source

Creates a new MonitorMixin::ConditionVariable associated with the receiver.

# File lib/monitor.rb, line 222
def new_cond
  return ConditionVariable.new(self)
end
synchronize() click to toggle source
Alias for: mon_synchronize
try_mon_enter() click to toggle source

For backward compatibility

Alias for: mon_try_enter


class MonitorMixin::ConditionVariable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class MonitorMixin::ConditionVariable

FIXME: This isn't documented in Nutshell.

Since MonitorMixin#new_cond returns a ConditionVariable, and the example above calls while_wait and signal, this class should be documented.

In Files

  • lib/monitor.rb

Parent

Object

Public Class Methods

new(monitor) click to toggle source
# File lib/monitor.rb, line 153
def initialize(monitor)
  @monitor = monitor
  @cond = ::ConditionVariable.new
end

Public Instance Methods

broadcast() click to toggle source

Wakes up all threads waiting for this lock.

# File lib/monitor.rb, line 146
def broadcast
  @monitor.__send__(:mon_check_owner)
  @cond.broadcast
end
signal() click to toggle source

Wakes up the first thread in line waiting for this lock.

# File lib/monitor.rb, line 138
def signal
  @monitor.__send__(:mon_check_owner)
  @cond.signal
end
wait(timeout = nil) click to toggle source

Releases the lock held in the associated monitor and waits; reacquires the lock on wakeup.

If timeout is given, this method returns after timeout seconds passed, even if no other thread doesn't signal.

# File lib/monitor.rb, line 106
def wait(timeout = nil)
  @monitor.__send__(:mon_check_owner)
  count = @monitor.__send__(:mon_exit_for_cond)
  begin
    @cond.wait(@monitor.instance_variable_get(:@mon_mutex), timeout)
    return true
  ensure
    @monitor.__send__(:mon_enter_for_cond, count)
  end
end
wait_until() click to toggle source

Calls wait repeatedly until the given block yields a truthy value.

# File lib/monitor.rb, line 129
def wait_until
  until yield
    wait
  end
end
wait_while() click to toggle source

Calls wait repeatedly while the given block yields a truthy value.

# File lib/monitor.rb, line 120
def wait_while
  while yield
    wait
  end
end


class MonitorMixin::ConditionVariable::Timeout - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class MonitorMixin::ConditionVariable::Timeout

In Files

  • lib/monitor.rb

Parent

Exception


module Mutex_m - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Mutex_m

mutex_m.rb

When 'mutex_m' is required, any object that extends or includes Mutex_m will be treated like a Mutex.

Start by requiring the standard library Mutex_m:

require "mutex_m.rb"

From here you can extend an object with Mutex instance methods:

obj = Object.new
obj.extend Mutex_m

Or mixin Mutex_m into your module to your class inherit Mutex instance methods.

class Foo
  include Mutex_m
  # ...
end
obj = Foo.new
# this obj can be handled like Mutex

In Files

  • lib/mutex_m.rb

Public Instance Methods

mu_lock() click to toggle source

See Mutex#lock

# File lib/mutex_m.rb, line 87
def mu_lock
  @_mutex.lock
end
mu_locked?() click to toggle source

See Mutex#locked?

# File lib/mutex_m.rb, line 77
def mu_locked?
  @_mutex.locked?
end
mu_synchronize(&block) click to toggle source

See Mutex#synchronize

# File lib/mutex_m.rb, line 72
def mu_synchronize(&block)
  @_mutex.synchronize(&block)
end
mu_try_lock() click to toggle source

See Mutex#try_lock

# File lib/mutex_m.rb, line 82
def mu_try_lock
  @_mutex.try_lock
end
mu_unlock() click to toggle source

See Mutex#unlock

# File lib/mutex_m.rb, line 92
def mu_unlock
  @_mutex.unlock
end
sleep(timeout = nil) click to toggle source

See Mutex#sleep

# File lib/mutex_m.rb, line 97
def sleep(timeout = nil)
  @_mutex.sleep(timeout)
end


module NKF - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module NKF

NKF - Ruby extension for Network Kanji Filter

Description

This is a Ruby Extension version of nkf (Network Kanji Filter). It converts the first argument and returns converted result. Conversion details are specified by flags as the first argument.

Nkf is a yet another kanji code converter among networks, hosts and terminals. It converts input kanji code to designated kanji code such as ISO-2022-JP, Shift_JIS, EUC-JP, UTF-8 or UTF-16.

One of the most unique faculty of nkf is the guess of the input kanji encodings. It currently recognizes ISO-2022-JP, Shift_JIS, EUC-JP, UTF-8 and UTF-16. So users needn't set the input kanji code explicitly.

By default, X0201 kana is converted into X0208 kana. For X0201 kana, SO/SI, SSO and ESC-(-I methods are supported. For automatic code detection, nkf assumes no X0201 kana in Shift_JIS. To accept X0201 in Shift_JIS, use -X, -x or -S.

Flags

-b -u

Output is buffered (DEFAULT), Output is unbuffered.

-j -s -e -w -w16 -w32

Output code is ISO-2022-JP (7bit JIS), Shift_JIS, EUC-JP, UTF-8N, UTF-16BE, UTF-32BE. Without this option and compile option, ISO-2022-JP is assumed.

-J -S -E -W -W16 -W32

Input assumption is JIS 7 bit, Shift_JIS, EUC-JP, UTF-8, UTF-16, UTF-32.

-J

Assume JIS input. It also accepts EUC-JP. This is the default. This flag does not exclude Shift_JIS.

-S

Assume Shift_JIS and X0201 kana input. It also accepts JIS. EUC-JP is recognized as X0201 kana. Without -x flag, X0201 kana (halfwidth kana) is converted into X0208.

-E

Assume EUC-JP input. It also accepts JIS. Same as -J.

-t

No conversion.

-i_

Output sequence to designate JIS-kanji. (DEFAULT B)

-o_

Output sequence to designate ASCII. (DEFAULT B)

-r

{de/en}crypt ROT13/47

-h –hiragana –katakana –katakana-hiragana

-h1 –hiragana

Katakana to Hiragana conversion.

-h2 –katakana

Hiragana to Katakana conversion.

-h3 –katakana-hiragana

Katakana to Hiragana and Hiragana to Katakana conversion.

-T

Text mode output (MS-DOS)

-l

ISO8859-1 (Latin-1) support

-f[m [- n]]

Folding on m length with n margin in a line. Without this option, fold length is 60 and fold margin is 10.

-F

New line preserving line folding.

-Z

Convert X0208 alphabet (Fullwidth Alphabets) to ASCII.

-Z -Z0

Convert X0208 alphabet to ASCII.

-Z1

Converts X0208 kankaku to single ASCII space.

-Z2

Converts X0208 kankaku to double ASCII spaces.

-Z3

Replacing Fullwidth >, <, “, & into '&gt;', '&lt;', '&quot;', '&amp;' as in HTML.

-X -x

Assume X0201 kana in MS-Kanji. With -X or without this option, X0201 is converted into X0208 Kana. With -x, try to preserve X0208 kana and do not convert X0201 kana to X0208. In JIS output, ESC-(-I is used. In EUC output, SSO is used.

-B

Assume broken JIS-Kanji input, which lost ESC. Useful when your site is using old B-News Nihongo patch.

-B1

allows any char after ESC-( or ESC-$.

-B2

forces ASCII after NL.

-I

Replacing non iso-2022-jp char into a geta character (substitute character in Japanese).

-d -c

Delete r in line feed, Add r in line feed.

-m

MIME ISO-2022-JP/ISO8859-1 decode. (DEFAULT) To see ISO8859-1 (Latin-1) -l is necessary.

-mB

Decode MIME base64 encoded stream. Remove header or other part before

conversion.

-mQ

Decode MIME quoted stream. '_' in quoted stream is converted to space.

-mN

Non-strict decoding.

It allows line break in the middle of the base64 encoding.

-m0

No MIME decode.

-M

MIME encode. Header style. All ASCII code and control characters are intact. Kanji conversion is performed before encoding, so this cannot be used as a picture encoder.

-MB

MIME encode Base64 stream.

-MQ

Perfome quoted encoding.

-l

Input and output code is ISO8859-1 (Latin-1) and ISO-2022-JP. -s, -e and -x are not compatible with this option.

-L

new line mode Without this option, nkf doesn't convert line breaks.

-Lu

unix (LF)

-Lw

windows (CRLF)

-Lm

mac (CR)

–fj –unix –mac –msdos –windows

convert for these system

–jis –euc –sjis –mime –base64

convert for named code

–jis-input –euc-input –sjis-input –mime-input –base64-input

assume input system

–ic=input codeset –oc=output codeset

Set the input or output codeset. NKF supports following codesets and those codeset name are case insensitive.

ISO-2022-JP

a.k.a. RFC1468, 7bit JIS, JUNET

EUC-JP (eucJP-nkf)

a.k.a. AT&T JIS, Japanese EUC, UJIS

eucJP-ascii

a.k.a. x-eucjp-open-19970715-ascii

eucJP-ms

a.k.a. x-eucjp-open-19970715-ms

CP51932

Microsoft Version of EUC-JP.

Shift_JIS

SJIS, MS-Kanji

Windows-31J

a.k.a. CP932

UTF-8

same as UTF-8N

UTF-8N

UTF-8 without BOM

UTF-8-BOM

UTF-8 with BOM

UTF-16

same as UTF-16BE

UTF-16BE

UTF-16 Big Endian without BOM

UTF-16BE-BOM

UTF-16 Big Endian with BOM

UTF-16LE

UTF-16 Little Endian without BOM

UTF-16LE-BOM

UTF-16 Little Endian with BOM

UTF-32

same as UTF-32BE

UTF-32BE

UTF-32 Big Endian without BOM

UTF-32BE-BOM

UTF-32 Big Endian with BOM

UTF-32LE

UTF-32 Little Endian without BOM

UTF-32LE-BOM

UTF-32 Little Endian with BOM

UTF8-MAC

NKDed UTF-8, a.k.a. UTF8-NFD (input only)

–fb-{skip, html, xml, perl, java, subchar}

Specify the way that nkf handles unassigned characters. Without this option, –fb-skip is assumed.

–prefix= escape character target character ..

When nkf converts to Shift_JIS, nkf adds a specified escape character to specified 2nd byte of Shift_JIS characters. 1st byte of argument is the escape character and following bytes are target characters.

–no-cp932ext

Handle the characters extended in CP932 as unassigned characters.

–no-best-fit-chars

When Unicode to Encoded byte conversion, don't convert characters which is not round trip safe. When Unicode to Unicode conversion, with this and -x option, nkf can be used as UTF converter. (In other words, without this and -x option, nkf doesn't save some characters)

When nkf convert string which related to path, you should use this opion.

–cap-input

Decode hex encoded characters.

–url-input

Unescape percent escaped characters.

–

Ignore rest of -option.

In Files

  • ext/nkf/nkf.c

Constants

ASCII
AUTO
BINARY
EUC
JIS
NKF_RELEASE_DATE

Release date of nkf

NKF_VERSION

Version of nkf

NOCONV
SJIS
UNKNOWN
UTF16
UTF32
UTF8
VERSION

Full version string of nkf

Public Class Methods

guess(str) → encoding click to toggle source

Returns guessed encoding of str by nkf routine.

static VALUE
rb_nkf_guess(VALUE obj, VALUE src)
{
    reinit();

    input_ctr = 0;
    StringValue(src);
    input = (unsigned char *)RSTRING_PTR(src);
    i_len = RSTRING_LENINT(src);

    guess_f = TRUE;
    kanji_convert( NULL );
    guess_f = FALSE;

    return rb_enc_from_encoding(rb_nkf_enc_get(get_guessed_code()));
}
nkf(opt, str) → string click to toggle source

Convert str and return converted result. Conversion details are specified by opt as String.

require 'nkf'
output = NKF.nkf("-s", input)

static VALUE
rb_nkf_convert(VALUE obj, VALUE opt, VALUE src)
{
    VALUE tmp;
    reinit();
    StringValue(opt);
    nkf_split_options(RSTRING_PTR(opt));
    if (!output_encoding) rb_raise(rb_eArgError, "no output encoding given");

    switch (nkf_enc_to_index(output_encoding)) {
    case UTF_8_BOM:    output_encoding = nkf_enc_from_index(UTF_8); break;
    case UTF_16BE_BOM: output_encoding = nkf_enc_from_index(UTF_16BE); break;
    case UTF_16LE_BOM: output_encoding = nkf_enc_from_index(UTF_16LE); break;
    case UTF_32BE_BOM: output_encoding = nkf_enc_from_index(UTF_32BE); break;
    case UTF_32LE_BOM: output_encoding = nkf_enc_from_index(UTF_32LE); break;
    }
    output_bom_f = FALSE;

    incsize = INCSIZE;

    input_ctr = 0;
    StringValue(src);
    input = (unsigned char *)RSTRING_PTR(src);
    i_len = RSTRING_LENINT(src);
    tmp = rb_str_new(0, i_len*3 + 10);

    output_ctr = 0;
    output     = (unsigned char *)RSTRING_PTR(tmp);
    o_len      = RSTRING_LENINT(tmp);
    *output    = '\0';

    /* use _result_ begin*/
    result = tmp;
    kanji_convert(NULL);
    result = Qnil;
    /* use _result_ end */

    rb_str_set_len(tmp, output_ctr);
    OBJ_INFECT(tmp, src);

    if (mimeout_f)
        rb_enc_associate(tmp, rb_usascii_encoding());
    else
        rb_enc_associate(tmp, rb_nkf_enc_get(nkf_enc_name(output_encoding)));

    return tmp;
}


module NQXML - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module NQXML

In Files

  • lib/xmlrpc/parser.rb


class NQXML::Node - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class NQXML::Node

In Files

  • lib/xmlrpc/parser.rb

Parent

Object

Public Instance Methods

[](index) click to toggle source
# File lib/xmlrpc/parser.rb, line 24
def [] (index)
  @children[index]
end
childNodes() click to toggle source
# File lib/xmlrpc/parser.rb, line 18
def childNodes
  @children
end
hasChildNodes() click to toggle source
# File lib/xmlrpc/parser.rb, line 21
def hasChildNodes
  not @children.empty?
end
nodeName() click to toggle source
# File lib/xmlrpc/parser.rb, line 41
def nodeName
  #TODO: error when wrong Entity-type
  @entity.name
end
nodeType() click to toggle source
# File lib/xmlrpc/parser.rb, line 28
def nodeType
  if @entity.instance_of? NQXML::Text then :TEXT
  elsif @entity.instance_of? NQXML::Comment then :COMMENT
  #elsif @entity.instance_of? NQXML::Element then :ELEMENT
  elsif @entity.instance_of? NQXML::Tag then :ELEMENT
  else :ELSE
  end
end
nodeValue() click to toggle source
# File lib/xmlrpc/parser.rb, line 37
def nodeValue
  #TODO: error when wrong Entity-type
  @entity.text
end
removeChild(node) click to toggle source
# File lib/xmlrpc/parser.rb, line 15
def removeChild(node)
  @children.delete(node)
end


module Net - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Net

In Files

  • lib/net/ftp.rb
  • lib/net/http/backward.rb
  • lib/net/http.rb
  • lib/net/imap.rb
  • lib/net/pop.rb
  • lib/net/protocol.rb
  • lib/net/smtp.rb
  • lib/net/telnet.rb

Constants

APOPSession

class aliases


class Net::APOPSession - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::APOPSession

This class is equivalent to POP3, except that it uses APOP authentication.

In Files

  • lib/net/pop.rb

Parent

Net::POP3

Public Instance Methods

apop?() click to toggle source

Always returns true.

# File lib/net/pop.rb, line 727
def apop?
  true
end


class Net::FTP - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::FTP

This class implements the File Transfer Protocol. If you have used a command-line FTP program, and are familiar with the commands, you will be able to use this class easily. Some extra features are included to take advantage of Ruby's style and strengths.

Example

require 'net/ftp'

Example 1

ftp = Net::FTP.new('example.com')
ftp.login
files = ftp.chdir('pub/lang/ruby/contrib')
files = ftp.list('n*')
ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024)
ftp.close

Example 2

Net::FTP.open('example.com') do |ftp|
  ftp.login
  files = ftp.chdir('pub/lang/ruby/contrib')
  files = ftp.list('n*')
  ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024)
end

Major Methods

The following are the methods most likely to be useful to users:

  • ::open

  • getbinaryfile

  • gettextfile

  • putbinaryfile

  • puttextfile

  • chdir

  • nlst

  • size

  • rename

  • delete

In Files

  • lib/net/ftp.rb

Parent

Object

Included Modules

  • MonitorMixin

Attributes

binary[R]

When true, transfers are performed in binary mode. Default: true.

debug_mode[RW]

When true, all traffic to and from the server is written to +$stdout+. Default: false.

last_response[R]

The server's last response.

last_response_code[R]

The server's last response code.

lastresp[R]

The server's last response code.

open_timeout[RW]

Number of seconds to wait for the connection to open. Any number may be used, including Floats for fractional seconds. If the FTP object cannot open a connection in this many seconds, it raises a Net::OpenTimeout exception. The default value is nil.

passive[RW]

When true, the connection is in passive mode. Default: false.

read_timeout[R]

Number of seconds to wait for one block to be read (via one read(2) call). Any number may be used, including Floats for fractional seconds. If the FTP object cannot read data in this many seconds, it raises a TimeoutError exception. The default value is 60 seconds.

resume[RW]

Sets or retrieves the resume status, which decides whether incomplete transfers are resumed or restarted. Default: false.

welcome[R]

The server's welcome message.

Public Class Methods

new(host = nil, user = nil, passwd = nil, acct = nil) click to toggle source

Creates and returns a new FTP object. If a host is given, a connection is made. Additionally, if the user is given, the given user name, password, and (optionally) account are used to log in. See login.

# File lib/net/ftp.rb, line 149
def initialize(host = nil, user = nil, passwd = nil, acct = nil)
  super()
  @binary = true
  @passive = false
  @debug_mode = false
  @resume = false
  @sock = NullSocket.new
  @logged_in = false
  @open_timeout = nil
  @read_timeout = 60
  if host
    connect(host)
    if user
      login(user, passwd, acct)
    end
  end
end
open(host, user = nil, passwd = nil, acct = nil) { |ftp| ... } click to toggle source

A synonym for FTP.new, but with a mandatory host parameter.

If a block is given, it is passed the FTP object, which will be closed when the block finishes, or when an exception is raised.

# File lib/net/ftp.rb, line 131
def FTP.open(host, user = nil, passwd = nil, acct = nil)
  if block_given?
    ftp = new(host, user, passwd, acct)
    begin
      yield ftp
    ensure
      ftp.close
    end
  else
    new(host, user, passwd, acct)
  end
end

Public Instance Methods

abort() click to toggle source

Aborts the previous command (ABOR command).

# File lib/net/ftp.rb, line 881
def abort
  line = "ABOR" + CRLF
  print "put: ABOR\n" if @debug_mode
  @sock.send(line, Socket::MSG_OOB)
  resp = getmultiline
  unless ["426", "226", "225"].include?(resp[0, 3])
    raise FTPProtoError, resp
  end
  return resp
end
acct(account) click to toggle source

Sends the ACCT command.

This is a less common FTP command, to send account information if the destination host requires it.

# File lib/net/ftp.rb, line 733
def acct(account)
  cmd = "ACCT " + account
  voidcmd(cmd)
end
binary=(newmode) click to toggle source

A setter to toggle transfers in binary mode. newmode is either true or false

# File lib/net/ftp.rb, line 169
def binary=(newmode)
  if newmode != @binary
    @binary = newmode
    send_type_command if @logged_in
  end
end
chdir(dirname) click to toggle source

Changes the (remote) directory.

# File lib/net/ftp.rb, line 803
def chdir(dirname)
  if dirname == ".."
    begin
      voidcmd("CDUP")
      return
    rescue FTPPermError => e
      if e.message[0, 3] != "500"
        raise e
      end
    end
  end
  cmd = "CWD " + dirname
  voidcmd(cmd)
end
close() click to toggle source

Closes the connection. Further operations are impossible until you open a new connection with connect.

# File lib/net/ftp.rb, line 951
def close
  if @sock and not @sock.closed?
    begin
      @sock.shutdown(Socket::SHUT_WR) rescue nil
      orig, self.read_timeout = self.read_timeout, 3
      @sock.read rescue nil
    ensure
      @sock.close
      self.read_timeout = orig
    end
  end
end
closed?() click to toggle source

Returns true iff the connection is closed.

# File lib/net/ftp.rb, line 967
def closed?
  @sock == nil or @sock.closed?
end
connect(host, port = FTP_PORT) click to toggle source

Establishes an FTP connection to host, optionally overriding the default port. If the environment variable SOCKS_SERVER is set, sets up the connection through a SOCKS proxy. Raises an exception (typically Errno::ECONNREFUSED) if the connection cannot be established.

# File lib/net/ftp.rb, line 243
def connect(host, port = FTP_PORT)
  if @debug_mode
    print "connect: ", host, ", ", port, "\n"
  end
  synchronize do
    @sock = open_socket(host, port)
    voidresp
  end
end
delete(filename) click to toggle source

Deletes a file on the server.

# File lib/net/ftp.rb, line 789
def delete(filename)
  resp = sendcmd("DELE " + filename)
  if resp[0, 3] == "250"
    return
  elsif resp[0] == 5
    raise FTPPermError, resp
  else
    raise FTPReplyError, resp
  end
end
dir(*args) click to toggle source
Alias for: list
get(remotefile, localfile = File.basename(remotefile), blocksize = DEFAULT_BLOCKSIZE) { |data| ... } click to toggle source

Retrieves remotefile in whatever mode the session is set (text or binary). See gettextfile and getbinaryfile.

# File lib/net/ftp.rb, line 662
def get(remotefile, localfile = File.basename(remotefile),
        blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
  if @binary
    getbinaryfile(remotefile, localfile, blocksize, &block)
  else
    gettextfile(remotefile, localfile, &block)
  end
end
getbinaryfile(remotefile, localfile = File.basename(remotefile), blocksize = DEFAULT_BLOCKSIZE) { |data| ... } click to toggle source

Retrieves remotefile in binary mode, storing the result in localfile. If localfile is nil, returns retrieved data. If a block is supplied, it is passed the retrieved data in blocksize chunks.

# File lib/net/ftp.rb, line 604
def getbinaryfile(remotefile, localfile = File.basename(remotefile),
                  blocksize = DEFAULT_BLOCKSIZE) # :yield: data
  result = nil
  if localfile
    if @resume
      rest_offset = File.size?(localfile)
      f = open(localfile, "a")
    else
      rest_offset = nil
      f = open(localfile, "w")
    end
  elsif !block_given?
    result = ""
  end
  begin
    f.binmode if localfile
    retrbinary("RETR " + remotefile.to_s, blocksize, rest_offset) do |data|
      f.write(data) if localfile
      yield(data) if block_given?
      result.concat(data) if result
    end
    return result
  ensure
    f.close if localfile
  end
end
getdir() click to toggle source
Alias for: pwd
gettextfile(remotefile, localfile = File.basename(remotefile)) { |line| ... } click to toggle source

Retrieves remotefile in ASCII (text) mode, storing the result in localfile. If localfile is nil, returns retrieved data. If a block is supplied, it is passed the retrieved data one line at a time.

# File lib/net/ftp.rb, line 638
def gettextfile(remotefile, localfile = File.basename(remotefile)) # :yield: line
  result = nil
  if localfile
    f = open(localfile, "w")
  elsif !block_given?
    result = ""
  end
  begin
    retrlines("RETR " + remotefile) do |line, newline|
      l = newline ? line + "\n" : line
      f.print(l) if localfile
      yield(line, newline) if block_given?
      result.concat(l) if result
    end
    return result
  ensure
    f.close if localfile
  end
end
help(arg = nil) click to toggle source

Issues the HELP command.

# File lib/net/ftp.rb, line 915
def help(arg = nil)
  cmd = "HELP"
  if arg
    cmd = cmd + " " + arg
  end
  sendcmd(cmd)
end
list(*args) { |line| ... } click to toggle source

Returns an array of file information in the directory (the output is like `ls -l`). If a block is given, it iterates through the listing.

# File lib/net/ftp.rb, line 757
def list(*args, &block) # :yield: line
  cmd = "LIST"
  args.each do |arg|
    cmd = cmd + " " + arg.to_s
  end
  if block
    retrlines(cmd, &block)
  else
    lines = []
    retrlines(cmd) do |line|
      lines << line
    end
    return lines
  end
end
Also aliased as: ls, dir
login(user = "anonymous", passwd = nil, acct = nil) click to toggle source

Logs in to the remote host. The session must have been previously connected. If user is the string “anonymous” and the password is nil, a password of user@host is synthesized. If the acct parameter is not nil, an FTP ACCT command is sent following the successful login. Raises an exception on error (typically Net::FTPPermError).

# File lib/net/ftp.rb, line 455
def login(user = "anonymous", passwd = nil, acct = nil)
  if user == "anonymous" and passwd == nil
    passwd = "anonymous@"
  end

  resp = ""
  synchronize do
    resp = sendcmd('USER ' + user)
    if resp[0] == 3
      raise FTPReplyError, resp if passwd.nil?
      resp = sendcmd('PASS ' + passwd)
    end
    if resp[0] == 3
      raise FTPReplyError, resp if acct.nil?
      resp = sendcmd('ACCT ' + acct)
    end
  end
  if resp[0] != 2
    raise FTPReplyError, resp
  end
  @welcome = resp
  send_type_command
  @logged_in = true
end
ls(*args) click to toggle source
Alias for: list
mdtm(filename) click to toggle source

Issues the MDTM command. TODO: more info.

# File lib/net/ftp.rb, line 905
def mdtm(filename)
  resp = sendcmd("MDTM " + filename)
  if resp[0, 3] == "213"
    return resp[3 .. -1].strip
  end
end
mkdir(dirname) click to toggle source

Creates a remote directory.

# File lib/net/ftp.rb, line 846
def mkdir(dirname)
  resp = sendcmd("MKD " + dirname)
  return parse257(resp)
end
mtime(filename, local = false) click to toggle source

Returns the last modification time of the (remote) file. If local is true, it is returned as a local time, otherwise it's a UTC time.

# File lib/net/ftp.rb, line 837
def mtime(filename, local = false)
  str = mdtm(filename)
  ary = str.scan(MDTM_REGEXP)[0].collect {|i| i.to_i}
  return local ? Time.local(*ary) : Time.gm(*ary)
end
nlst(dir = nil) click to toggle source

Returns an array of filenames in the remote directory.

# File lib/net/ftp.rb, line 741
def nlst(dir = nil)
  cmd = "NLST"
  if dir
    cmd = cmd + " " + dir
  end
  files = []
  retrlines(cmd) do |line|
    files.push(line)
  end
  return files
end
noop() click to toggle source

Issues a NOOP command.

Does nothing except return a response.

# File lib/net/ftp.rb, line 935
def noop
  voidcmd("NOOP")
end
put(localfile, remotefile = File.basename(localfile), blocksize = DEFAULT_BLOCKSIZE, &block) click to toggle source

Transfers localfile to the server in whatever mode the session is set (text or binary). See puttextfile and putbinaryfile.

# File lib/net/ftp.rb, line 718
def put(localfile, remotefile = File.basename(localfile),
        blocksize = DEFAULT_BLOCKSIZE, &block)
  if @binary
    putbinaryfile(localfile, remotefile, blocksize, &block)
  else
    puttextfile(localfile, remotefile, &block)
  end
end
putbinaryfile(localfile, remotefile = File.basename(localfile), blocksize = DEFAULT_BLOCKSIZE) { |data| ... } click to toggle source

Transfers localfile to the server in binary mode, storing the result in remotefile. If a block is supplied, calls it, passing in the transmitted data in blocksize chunks.

# File lib/net/ftp.rb, line 676
def putbinaryfile(localfile, remotefile = File.basename(localfile),
                  blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
  if @resume
    begin
      rest_offset = size(remotefile)
    rescue Net::FTPPermError
      rest_offset = nil
    end
  else
    rest_offset = nil
  end
  f = open(localfile)
  begin
    f.binmode
    if rest_offset
      storbinary("APPE " + remotefile, f, blocksize, rest_offset, &block)
    else
      storbinary("STOR " + remotefile, f, blocksize, rest_offset, &block)
    end
  ensure
    f.close
  end
end
puttextfile(localfile, remotefile = File.basename(localfile)) { |line| ... } click to toggle source

Transfers localfile to the server in ASCII (text) mode, storing the result in remotefile. If callback or an associated block is supplied, calls it, passing in the transmitted data one line at a time.

# File lib/net/ftp.rb, line 705
def puttextfile(localfile, remotefile = File.basename(localfile), &block) # :yield: line
  f = open(localfile)
  begin
    storlines("STOR " + remotefile, f, &block)
  ensure
    f.close
  end
end
pwd() click to toggle source

Returns the current remote directory.

# File lib/net/ftp.rb, line 861
def pwd
  resp = sendcmd("PWD")
  return parse257(resp)
end
Also aliased as: getdir
quit() click to toggle source

Exits the FTP session.

# File lib/net/ftp.rb, line 926
def quit
  voidcmd("QUIT")
end
read_timeout=(sec) click to toggle source

Setter for the #read_timeout attribute.

# File lib/net/ftp.rb, line 110
def read_timeout=(sec)
  @sock.read_timeout = sec
  @read_timeout = sec
end
rename(fromname, toname) click to toggle source

Renames a file on the server.

# File lib/net/ftp.rb, line 778
def rename(fromname, toname)
  resp = sendcmd("RNFR " + fromname)
  if resp[0] != 3
    raise FTPReplyError, resp
  end
  voidcmd("RNTO " + toname)
end
retrbinary(cmd, blocksize, rest_offset = nil) { |data| ... } click to toggle source

Puts the connection into binary (image) mode, issues the given command, and fetches the data returned, passing it to the associated block in chunks of blocksize characters. Note that cmd is a server command (such as “RETR myfile”).

# File lib/net/ftp.rb, line 486
def retrbinary(cmd, blocksize, rest_offset = nil) # :yield: data
  synchronize do
    with_binary(true) do
      begin
        conn = transfercmd(cmd, rest_offset)
        loop do
          data = conn.read(blocksize)
          break if data == nil
          yield(data)
        end
        conn.shutdown(Socket::SHUT_WR)
        conn.read_timeout = 1
        conn.read
      ensure
        conn.close if conn
      end
      voidresp
    end
  end
end
retrlines(cmd) { |line| ... } click to toggle source

Puts the connection into ASCII (text) mode, issues the given command, and passes the resulting data, one line at a time, to the associated block. If no block is given, prints the lines. Note that cmd is a server command (such as “RETR myfile”).

# File lib/net/ftp.rb, line 513
def retrlines(cmd) # :yield: line
  synchronize do
    with_binary(false) do
      begin
        conn = transfercmd(cmd)
        loop do
          line = conn.gets
          break if line == nil
          yield(line.sub(/\r?\n\z/, ""), !line.match(/\n\z/).nil?)
        end
        conn.shutdown(Socket::SHUT_WR)
        conn.read_timeout = 1
        conn.read
      ensure
        conn.close if conn
      end
      voidresp
    end
  end
end
rmdir(dirname) click to toggle source

Removes a remote directory.

# File lib/net/ftp.rb, line 854
def rmdir(dirname)
  voidcmd("RMD " + dirname)
end
sendcmd(cmd) click to toggle source

Sends a command and returns the response.

# File lib/net/ftp.rb, line 348
def sendcmd(cmd)
  synchronize do
    putline(cmd)
    return getresp
  end
end
set_socket(sock, get_greeting = true) click to toggle source

WRITEME or make private

# File lib/net/ftp.rb, line 256
def set_socket(sock, get_greeting = true)
  synchronize do
    @sock = sock
    if get_greeting
      voidresp
    end
  end
end
site(arg) click to toggle source

Issues a SITE command.

# File lib/net/ftp.rb, line 942
def site(arg)
  cmd = "SITE " + arg
  voidcmd(cmd)
end
size(filename) click to toggle source

Returns the size of the given (remote) filename.

# File lib/net/ftp.rb, line 821
def size(filename)
  with_binary(true) do
    resp = sendcmd("SIZE " + filename)
    if resp[0, 3] != "213"
      raise FTPReplyError, resp
    end
    return resp[3..-1].strip.to_i
  end
end
status() click to toggle source

Returns the status (STAT command).

# File lib/net/ftp.rb, line 895
def status
  line = "STAT" + CRLF
  print "put: STAT\n" if @debug_mode
  @sock.send(line, Socket::MSG_OOB)
  return getresp
end
storbinary(cmd, file, blocksize, rest_offset = nil) { |data| ... } click to toggle source

Puts the connection into binary (image) mode, issues the given server-side command (such as “STOR myfile”), and sends the contents of the file named file to the server. If the optional block is given, it also passes it the data, in chunks of blocksize characters.

# File lib/net/ftp.rb, line 540
def storbinary(cmd, file, blocksize, rest_offset = nil) # :yield: data
  if rest_offset
    file.seek(rest_offset, IO::SEEK_SET)
  end
  synchronize do
    with_binary(true) do
      conn = transfercmd(cmd)
      loop do
        buf = file.read(blocksize)
        break if buf == nil
        conn.write(buf)
        yield(buf) if block_given?
      end
      conn.close
      voidresp
    end
  end
rescue Errno::EPIPE
  # EPIPE, in this case, means that the data connection was unexpectedly
  # terminated.  Rather than just raising EPIPE to the caller, check the
  # response on the control connection.  If getresp doesn't raise a more
  # appropriate exception, re-raise the original exception.
  getresp
  raise
end
storlines(cmd, file) { |line| ... } click to toggle source

Puts the connection into ASCII (text) mode, issues the given server-side command (such as “STOR myfile”), and sends the contents of the file named file to the server, one line at a time. If the optional block is given, it also passes it the lines.

# File lib/net/ftp.rb, line 572
def storlines(cmd, file) # :yield: line
  synchronize do
    with_binary(false) do
      conn = transfercmd(cmd)
      loop do
        buf = file.gets
        break if buf == nil
        if buf[-2, 2] != CRLF
          buf = buf.chomp + CRLF
        end
        conn.write(buf)
        yield(buf) if block_given?
      end
      conn.close
      voidresp
    end
  end
rescue Errno::EPIPE
  # EPIPE, in this case, means that the data connection was unexpectedly
  # terminated.  Rather than just raising EPIPE to the caller, check the
  # response on the control connection.  If getresp doesn't raise a more
  # appropriate exception, re-raise the original exception.
  getresp
  raise
end
system() click to toggle source

Returns system information.

# File lib/net/ftp.rb, line 870
def system
  resp = sendcmd("SYST")
  if resp[0, 3] != "215"
    raise FTPReplyError, resp
  end
  return resp[4 .. -1]
end
voidcmd(cmd) click to toggle source

Sends a command and expect a response beginning with '2'.

# File lib/net/ftp.rb, line 358
def voidcmd(cmd)
  synchronize do
    putline(cmd)
    voidresp
  end
end


class Net::FTP::BufferedSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::FTP::BufferedSocket

In Files

  • lib/net/ftp.rb

Parent

BufferedIO


class Net::FTP::NullSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::FTP::NullSocket

In Files

  • lib/net/ftp.rb

Parent

Object


class Net::FTPConnectionError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::FTPConnectionError

In Files

  • lib/net/ftp.rb

Parent

Net::FTPError


class Net::FTPError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::FTPError

In Files

  • lib/net/ftp.rb

Parent

StandardError


class Net::FTPPermError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::FTPPermError

In Files

  • lib/net/ftp.rb

Parent

Net::FTPError


class Net::FTPProtoError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::FTPProtoError

In Files

  • lib/net/ftp.rb

Parent

Net::FTPError


class Net::FTPReplyError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::FTPReplyError

In Files

  • lib/net/ftp.rb

Parent

Net::FTPError


class Net::FTPTempError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::FTPTempError

In Files

  • lib/net/ftp.rb

Parent

Net::FTPError


class Net::HTTP - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP

An HTTP client API for Ruby.

Net::HTTP provides a rich library which can be used to build HTTP user-agents. For more details about HTTP see [RFC2616](www.ietf.org/rfc/rfc2616.txt)

Net::HTTP is designed to work closely with URI. URI::Generic#host, URI::Generic#port and URI::HTTP#request_uri are designed to work with Net::HTTP.

If you are only performing a few GET requests you should try OpenURI.

Simple Examples

All examples assume you have loaded Net::HTTP with:

require 'net/http'

This will also require 'uri' so you don't need to require it separately.

The Net::HTTP methods in the following section do not persist connections. They are not recommended if you are performing many HTTP requests.

GET

Net::HTTP.get('example.com', '/index.html') # => String

GET by URI

uri = URI('http://example.com/index.html?count=10')
Net::HTTP.get(uri) # => String

GET with Dynamic Parameters

uri = URI('http://example.com/index.html')
params = { :limit => 10, :page => 3 }
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
puts res.body if res.is_a?(Net::HTTPSuccess)

POST

uri = URI('http://www.example.com/search.cgi')
res = Net::HTTP.post_form(uri, 'q' => 'ruby', 'max' => '50')
puts res.body

POST with Multiple Values

uri = URI('http://www.example.com/search.cgi')
res = Net::HTTP.post_form(uri, 'q' => ['ruby', 'perl'], 'max' => '50')
puts res.body

How to use Net::HTTP

The following example code can be used as the basis of a HTTP user-agent which can perform a variety of request types using persistent connections.

uri = URI('http://example.com/some_path?query=string')

Net::HTTP.start(uri.host, uri.port) do |http|
  request = Net::HTTP::Get.new uri

  response = http.request request # Net::HTTPResponse object
end

::start immediately creates a connection to an HTTP server which is kept open for the duration of the block. The connection will remain open for multiple requests in the block if the server indicates it supports persistent connections.

The request types Net::HTTP supports are listed below in the section “HTTP Request Classes”.

If you wish to re-use a connection across multiple HTTP requests without automatically closing it you can use ::new instead of ::start. request will automatically open a connection to the server if one is not currently open. You can manually close the connection with finish.

For all the Net::HTTP request objects and shortcut request methods you may supply either a String for the request path or a URI from which Net::HTTP will extract the request path.

Response Data

uri = URI('http://example.com/index.html')
res = Net::HTTP.get_response(uri)

# Headers
res['Set-Cookie']            # => String
res.get_fields('set-cookie') # => Array
res.to_hash['set-cookie']    # => Array
puts "Headers: #{res.to_hash.inspect}"

# Status
puts res.code       # => '200'
puts res.message    # => 'OK'
puts res.class.name # => 'HTTPOK'

# Body
puts res.body if res.response_body_permitted?

Following Redirection

Each Net::HTTPResponse object belongs to a class for its response code.

For example, all 2XX responses are instances of a Net::HTTPSuccess subclass, a 3XX response is an instance of a Net::HTTPRedirection subclass and a 200 response is an instance of the Net::HTTPOK class. For details of response classes, see the section “HTTP Response Classes” below.

Using a case statement you can handle various types of responses properly:

def fetch(uri_str, limit = 10)
  # You should choose a better exception.
  raise ArgumentError, 'too many HTTP redirects' if limit == 0

  response = Net::HTTP.get_response(URI(uri_str))

  case response
  when Net::HTTPSuccess then
    response
  when Net::HTTPRedirection then
    location = response['location']
    warn "redirected to #{location}"
    fetch(location, limit - 1)
  else
    response.value
  end
end

print fetch('http://www.ruby-lang.org')

POST

A POST can be made using the Net::HTTP::Post request class. This example creates a urlencoded POST body:

uri = URI('http://www.example.com/todo.cgi')
req = Net::HTTP::Post.new(uri)
req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')

res = Net::HTTP.start(uri.hostname, uri.port) do |http|
  http.request(req)
end

case res
when Net::HTTPSuccess, Net::HTTPRedirection
  # OK
else
  res.value
end

At this time Net::HTTP does not support multipart/form-data. To send multipart/form-data use Net::HTTPGenericRequest#body= and Net::HTTPRequest#content_type=:

req = Net::HTTP::Post.new(uri)
req.body = multipart_data
req.content_type = 'multipart/form-data'

Other requests that can contain a body such as PUT can be created in the same way using the corresponding request class (Net::HTTP::Put).

Setting Headers

The following example performs a conditional GET using the If-Modified-Since header. If the files has not been modified since the time in the header a Not Modified response will be returned. See RFC 2616 section 9.3 for further details.

uri = URI('http://example.com/cached_response')
file = File.stat 'cached_response'

req = Net::HTTP::Get.new(uri)
req['If-Modified-Since'] = file.mtime.rfc2822

res = Net::HTTP.start(uri.hostname, uri.port) {|http|
  http.request(req)
}

open 'cached_response', 'w' do |io|
  io.write res.body
end if res.is_a?(Net::HTTPSuccess)

Basic Authentication

Basic authentication is performed according to [RFC2617](www.ietf.org/rfc/rfc2617.txt)

uri = URI('http://example.com/index.html?key=value')

req = Net::HTTP::Get.new(uri)
req.basic_auth 'user', 'pass'

res = Net::HTTP.start(uri.hostname, uri.port) {|http|
  http.request(req)
}
puts res.body

Streaming Response Bodies

By default Net::HTTP reads an entire response into memory. If you are handling large files or wish to implement a progress bar you can instead stream the body directly to an IO.

uri = URI('http://example.com/large_file')

Net::HTTP.start(uri.host, uri.port) do |http|
  request = Net::HTTP::Get.new uri

  http.request request do |response|
    open 'large_file', 'w' do |io|
      response.read_body do |chunk|
        io.write chunk
      end
    end
  end
end

HTTPS

HTTPS is enabled for an HTTP connection by #use_ssl=.

uri = URI('https://secure.example.com/some_path?query=string')

Net::HTTP.start(uri.host, uri.port,
  :use_ssl => uri.scheme == 'https') do |http|
  request = Net::HTTP::Get.new uri

  response = http.request request # Net::HTTPResponse object
end

In previous versions of ruby you would need to require 'net/https' to use HTTPS. This is no longer true.

Proxies

Net::HTTP will automatically create a proxy from the http_proxy environment variable if it is present. To disable use of http_proxy, pass nil for the proxy address.

You may also create a custom proxy:

proxy_addr = 'your.proxy.host'
proxy_port = 8080

Net::HTTP.new('example.com', nil, proxy_addr, proxy_port).start { |http|
  # always proxy via your.proxy.addr:8080
}

See ::new for further details and examples such as proxies that require a username and password.

Compression

Net::HTTP automatically adds Accept-Encoding for compression of response bodies and automatically decompresses gzip and deflate responses unless a Range header was sent.

Compression can be disabled through the Accept-Encoding: identity header.

HTTP Request Classes

Here is the HTTP request class hierarchy.

  • Net::HTTPRequest

    • Net::HTTP::Get

    • Net::HTTP::Head

    • Net::HTTP::Post

    • Net::HTTP::Patch

    • Net::HTTP::Put

    • Net::HTTP::Proppatch

    • Net::HTTP::Lock

    • Net::HTTP::Unlock

    • Net::HTTP::Options

    • Net::HTTP::Propfind

    • Net::HTTP::Delete

    • Net::HTTP::Move

    • Net::HTTP::Copy

    • Net::HTTP::Mkcol

    • Net::HTTP::Trace

HTTP Response Classes

Here is HTTP response class hierarchy. All classes are defined in Net module and are subclasses of Net::HTTPResponse.

HTTPUnknownResponse

For unhandled HTTP extensions

HTTPInformation

1xx

HTTPContinue

100

HTTPSwitchProtocol

101

HTTPSuccess

2xx

HTTPOK

200

HTTPCreated

201

HTTPAccepted

202

HTTPNonAuthoritativeInformation

203

HTTPNoContent

204

HTTPResetContent

205

HTTPPartialContent

206

HTTPMultiStatus

207

HTTPRedirection

3xx

HTTPMultipleChoices

300

HTTPMovedPermanently

301

HTTPFound

302

HTTPSeeOther

303

HTTPNotModified

304

HTTPUseProxy

305

HTTPTemporaryRedirect

307

HTTPClientError

4xx

HTTPBadRequest

400

HTTPUnauthorized

401

HTTPPaymentRequired

402

HTTPForbidden

403

HTTPNotFound

404

HTTPMethodNotAllowed

405

HTTPNotAcceptable

406

HTTPProxyAuthenticationRequired

407

HTTPRequestTimeOut

408

HTTPConflict

409

HTTPGone

410

HTTPLengthRequired

411

HTTPPreconditionFailed

412

HTTPRequestEntityTooLarge

413

HTTPRequestURITooLong

414

HTTPUnsupportedMediaType

415

HTTPRequestedRangeNotSatisfiable

416

HTTPExpectationFailed

417

HTTPUnprocessableEntity

422

HTTPLocked

423

HTTPFailedDependency

424

HTTPUpgradeRequired

426

HTTPPreconditionRequired

428

HTTPTooManyRequests

429

HTTPRequestHeaderFieldsTooLarge

431

HTTPServerError

5xx

HTTPInternalServerError

500

HTTPNotImplemented

501

HTTPBadGateway

502

HTTPServiceUnavailable

503

HTTPGatewayTimeOut

504

HTTPVersionNotSupported

505

HTTPInsufficientStorage

507

HTTPNetworkAuthenticationRequired

511

There is also the Net::HTTPBadResponse exception which is raised when there is a protocol error.

In Files

  • lib/net/http/backward.rb
  • lib/net/http.rb

Parent

Protocol

Constants

ProxyMod
SSL_ATTRIBUTES
SSL_IVNAMES

Attributes

proxy_address[R]

Address of proxy host. If Net::HTTP does not use a proxy, nil.

proxy_pass[R]

User password for accessing proxy. If Net::HTTP does not use a proxy, nil.

proxy_port[R]

Port number of proxy host. If Net::HTTP does not use a proxy, nil.

proxy_user[R]

User name for accessing proxy. If Net::HTTP does not use a proxy, nil.

address[R]

The DNS host name or IP address to connect to.

ca_file[RW]

Sets path of a CA certification file in PEM format.

The file can contain several CA certificates.

ca_path[RW]

Sets path of a CA certification directory containing certifications in PEM format.

cert[RW]

Sets an OpenSSL::X509::Certificate object as client certificate. (This method is appeared in Michal Rokos's OpenSSL extension).

cert_store[RW]

Sets the X509::Store to verify peer certificate.

ciphers[RW]

Sets the available ciphers. See OpenSSL::SSL::SSLContext#ciphers=

close_on_empty_response[RW]
continue_timeout[R]

Seconds to wait for 100 Continue response. If the HTTP object does not receive a response in this many seconds it sends the request body. The default value is nil.

keep_alive_timeout[RW]

Seconds to reuse the connection of the previous request. If the idle time is less than this Keep-Alive Timeout, Net::HTTP reuses the TCP/IP socket used by the previous communication. The default value is 2 seconds.

key[RW]

Sets an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object. (This method is appeared in Michal Rokos's OpenSSL extension.)

local_host[RW]

The local host used to estabilish the connection.

local_port[RW]

The local port used to estabilish the connection.

open_timeout[RW]

Number of seconds to wait for the connection to open. Any number may be used, including Floats for fractional seconds. If the HTTP object cannot open a connection in this many seconds, it raises a Net::OpenTimeout exception. The default value is nil.

port[R]

The port number to connect to.

proxy_address[W]
proxy_from_env[W]
proxy_pass[W]
proxy_port[W]
proxy_user[W]
read_timeout[R]

Number of seconds to wait for one block to be read (via one read(2) call). Any number may be used, including Floats for fractional seconds. If the HTTP object cannot read data in this many seconds, it raises a Net::ReadTimeout exception. The default value is 60 seconds.

ssl_timeout[RW]

Sets the SSL timeout seconds.

ssl_version[RW]

Sets the SSL version. See OpenSSL::SSL::SSLContext#ssl_version=

verify_callback[RW]

Sets the verify callback for the server certification verification.

verify_depth[RW]

Sets the maximum depth for the certificate chain verification.

verify_mode[RW]

Sets the flags for server the certification verification at beginning of SSL/TLS session.

OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER are acceptable.

Public Class Methods

Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil) click to toggle source

Creates an HTTP proxy class which behaves like Net::HTTP, but performs all access via the specified proxy.

This class is obsolete. You may pass these same parameters directly to ::new. See ::new for details of the arguments.

# File lib/net/http.rb, line 970
def HTTP.Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil)
  return self unless p_addr

  Class.new(self) {
    @is_proxy_class = true

    if p_addr == :ENV then
      @proxy_from_env = true
      @proxy_address = nil
      @proxy_port    = nil
    else
      @proxy_from_env = false
      @proxy_address = p_addr
      @proxy_port    = p_port || default_port
    end

    @proxy_user = p_user
    @proxy_pass = p_pass
  }
end
default_port() click to toggle source

The default port to use for HTTP requests; defaults to 80.

# File lib/net/http.rb, line 517
def HTTP.default_port
  http_default_port()
end
get(uri_or_host, path = nil, port = nil) click to toggle source

Sends a GET request to the target and returns the HTTP response as a string. The target can either be specified as (uri), or as (host, path, port = 80); so:

print Net::HTTP.get(URI('http://www.example.com/index.html'))

or:

print Net::HTTP.get('www.example.com', '/index.html')
# File lib/net/http.rb, line 453
def HTTP.get(uri_or_host, path = nil, port = nil)
  get_response(uri_or_host, path, port).body
end
get_print(uri_or_host, path = nil, port = nil) click to toggle source

Gets the body text from the target and outputs it to $stdout. The target can either be specified as (uri), or as (host, path, port = 80); so:

Net::HTTP.get_print URI('http://www.example.com/index.html')

or:

Net::HTTP.get_print 'www.example.com', '/index.html'
# File lib/net/http.rb, line 434
def HTTP.get_print(uri_or_host, path = nil, port = nil)
  get_response(uri_or_host, path, port) {|res|
    res.read_body do |chunk|
      $stdout.print chunk
    end
  }
  nil
end
get_response(uri_or_host, path = nil, port = nil, &block) click to toggle source

Sends a GET request to the target and returns the HTTP response as a Net::HTTPResponse object. The target can either be specified as (uri), or as (host, path, port = 80); so:

res = Net::HTTP.get_response(URI('http://www.example.com/index.html'))
print res.body

or:

res = Net::HTTP.get_response('www.example.com', '/index.html')
print res.body
# File lib/net/http.rb, line 469
def HTTP.get_response(uri_or_host, path = nil, port = nil, &block)
  if path
    host = uri_or_host
    new(host, port || HTTP.default_port).start {|http|
      return http.request_get(path, &block)
    }
  else
    uri = uri_or_host
    start(uri.hostname, uri.port,
          :use_ssl => uri.scheme == 'https') {|http|
      return http.request_get(uri, &block)
    }
  end
end
http_default_port() click to toggle source

The default port to use for HTTP requests; defaults to 80.

# File lib/net/http.rb, line 522
def HTTP.http_default_port
  80
end
https_default_port() click to toggle source

The default port to use for HTTPS requests; defaults to 443.

# File lib/net/http.rb, line 527
def HTTP.https_default_port
  443
end
is_version_1_2?() click to toggle source
Alias for: version_1_2?
new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil) click to toggle source

Creates a new Net::HTTP object without opening a TCP connection or HTTP session.

The address should be a DNS hostname or IP address, the port is the port the server operates on. If no port is given the default port for HTTP or HTTPS is used.

If none of the p_ arguments are given, the proxy host and port are taken from the http_proxy environment variable (or its uppercase equivalent) if present. If the proxy requires authentication you must supply it by hand. See URI::Generic#find_proxy for details of proxy detection from the environment. To disable proxy detection set p_addr to nil.

If you are connecting to a custom proxy, p_addr the DNS name or IP address of the proxy host, p_port the port to use to access the proxy, and p_user and p_pass the username and password if authorization is required to use the proxy.

# File lib/net/http.rb, line 608
def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil)
  http = super address, port

  if proxy_class? then # from Net::HTTP::Proxy()
    http.proxy_from_env = @proxy_from_env
    http.proxy_address  = @proxy_address
    http.proxy_port     = @proxy_port
    http.proxy_user     = @proxy_user
    http.proxy_pass     = @proxy_pass
  elsif p_addr == :ENV then
    http.proxy_from_env = true
  else
    http.proxy_address = p_addr
    http.proxy_port    = p_port || default_port
    http.proxy_user    = p_user
    http.proxy_pass    = p_pass
  end

  http
end
Also aliased as: newobj
new(address, port = nil) click to toggle source

Creates a new Net::HTTP object for the specified server address, without opening the TCP connection or initializing the HTTP session. The address should be a DNS hostname or IP address.

# File lib/net/http.rb, line 632
def initialize(address, port = nil)
  @address = address
  @port    = (port || HTTP.default_port)
  @local_host = nil
  @local_port = nil
  @curr_http_version = HTTPVersion
  @keep_alive_timeout = 2
  @last_communicated = nil
  @close_on_empty_response = false
  @socket  = nil
  @started = false
  @open_timeout = nil
  @read_timeout = 60
  @continue_timeout = nil
  @debug_output = nil

  @proxy_from_env = false
  @proxy_uri      = nil
  @proxy_address  = nil
  @proxy_port     = nil
  @proxy_user     = nil
  @proxy_pass     = nil

  @use_ssl = false
  @ssl_context = nil
  @ssl_session = nil
  @enable_post_connection_check = true
  @sspi_enabled = false
  SSL_IVNAMES.each do |ivname|
    instance_variable_set ivname, nil
  end
end
newobj(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil) click to toggle source
Alias for: new
post_form(url, params) click to toggle source

Posts HTML form data to the specified URI object. The form data must be provided as a Hash mapping from String to String. Example:

{ "cmd" => "search", "q" => "ruby", "max" => "50" }

This method also does Basic Authentication iff url.user exists. But userinfo for authentication is deprecated (RFC3986). So this feature will be removed.

Example:

require 'net/http'
require 'uri'

Net::HTTP.post_form URI('http://www.example.com/search.cgi'),
                    { "q" => "ruby", "max" => "50" }

# File lib/net/http.rb, line 502
def HTTP.post_form(url, params)
  req = Post.new(url)
  req.form_data = params
  req.basic_auth url.user, url.password if url.user
  start(url.hostname, url.port,
        :use_ssl => url.scheme == 'https' ) {|http|
    http.request(req)
  }
end
proxy_class?() click to toggle source

returns true if self is a class which was created by HTTP::Proxy.

# File lib/net/http.rb, line 993
def proxy_class?
  defined?(@is_proxy_class) ? @is_proxy_class : false
end
start(address, port, p_addr, p_port, p_user, p_pass, &block) click to toggle source
start(address, port=nil, p_addr=nil, p_port=nil, p_user=nil, p_pass=nil, opt, &block)

Creates a new Net::HTTP object, then additionally opens the TCP connection and HTTP session.

Arguments are the following:

address

hostname or IP address of the server

port

port of the server

p_addr

address of proxy

p_port

port of proxy

p_user

user of proxy

p_pass

pass of proxy

opt

optional hash

opt sets following values by its accessor. The keys are #ca_file, #ca_path, cert, #cert_store, ciphers, #close_on_empty_response, key, #open_timeout, #read_timeout, #ssl_timeout, #ssl_version, use_ssl, #verify_callback, #verify_depth and verify_mode. If you set :use_ssl as true, you can use https and default value of #verify_mode is set as OpenSSL::SSL::VERIFY_PEER.

If the optional block is given, the newly created Net::HTTP object is passed to it and closed when the block finishes. In this case, the return value of this method is the return value of the block. If no block is given, the return value of this method is the newly created Net::HTTP object itself, and the caller is responsible for closing it upon completion using the finish() method.

# File lib/net/http.rb, line 565
def HTTP.start(address, *arg, &block) # :yield: +http+
  arg.pop if opt = Hash.try_convert(arg[-1])
  port, p_addr, p_port, p_user, p_pass = *arg
  port = https_default_port if !port && opt && opt[:use_ssl]
  http = new(address, port, p_addr, p_port, p_user, p_pass)

  if opt
    if opt[:use_ssl]
      opt = {verify_mode: OpenSSL::SSL::VERIFY_PEER}.update(opt)
    end
    http.methods.grep(/\A(\w+)=\z/) do |meth|
      key = $1.to_sym
      opt.key?(key) or next
      http.__send__(meth, opt[key])
    end
  end

  http.start(&block)
end
version_1_2() click to toggle source

Turns on net/http 1.2 (ruby 1.8) features. Defaults to ON in ruby 1.8 or later.

# File lib/net/http.rb, line 400
def HTTP.version_1_2
  true
end
version_1_2?() click to toggle source

Returns true if net/http is in version 1.2 mode. Defaults to true.

# File lib/net/http.rb, line 406
def HTTP.version_1_2?
  true
end
Also aliased as: is_version_1_2?

Public Instance Methods

active?() click to toggle source
Alias for: started?
continue_timeout=(sec) click to toggle source

Setter for the #continue_timeout attribute.

# File lib/net/http.rb, line 725
def continue_timeout=(sec)
  @socket.continue_timeout = sec if @socket
  @continue_timeout = sec
end
copy(path, initheader = nil) click to toggle source

Sends a COPY request to the path and gets a response, as an HTTPResponse object.

# File lib/net/http.rb, line 1236
def copy(path, initheader = nil)
  request(Copy.new(path, initheader))
end
delete(path, initheader = {'Depth' => 'Infinity'}) click to toggle source

Sends a DELETE request to the path and gets a response, as an HTTPResponse object.

# File lib/net/http.rb, line 1224
def delete(path, initheader = {'Depth' => 'Infinity'})
  request(Delete.new(path, initheader))
end
finish() click to toggle source

Finishes the HTTP session and closes the TCP connection. Raises IOError if the session has not been started.

# File lib/net/http.rb, line 939
def finish
  raise IOError, 'HTTP session not yet started' unless started?
  do_finish
end
get(path, initheader = {}, dest = nil) { |body_segment| ... } click to toggle source

Retrieves data from path on the connected-to host which may be an absolute path String or a URI to extract the path from.

initheader must be a Hash like { 'Accept' => '/', … }, and it defaults to an empty hash. If initheader doesn't have the key 'accept-encoding', then a value of “gzip;q=1.0,deflate;q=0.6,identity;q=0.3” is used, so that gzip compression is used in preference to deflate compression, which is used in preference to no compression. Ruby doesn't have libraries to support the compress (Lempel-Ziv) compression, so that is not supported. The intent of this is to reduce bandwidth by default. If this routine sets up compression, then it does the decompression also, removing the header as well to prevent confusion. Otherwise it leaves the body as it found it.

This method returns a Net::HTTPResponse object.

If called with a block, yields each fragment of the entity body in turn as a string as it is read from the socket. Note that in this case, the returned response object will not contain a (meaningful) body.

dest argument is obsolete. It still works but you must not use it.

This method never raises an exception.

response = http.get('/index.html')

# using block
File.open('result.txt', 'w') {|f|
  http.get('/~foo/') do |str|
    f.write str
  end
}

# File lib/net/http.rb, line 1124
def get(path, initheader = {}, dest = nil, &block) # :yield: +body_segment+
  res = nil
  request(Get.new(path, initheader)) {|r|
    r.read_body dest, &block
    res = r
  }
  res
end
get2(path, initheader = nil) click to toggle source
Alias for: request_get
head(path, initheader = nil) click to toggle source

Gets only the header from path on the connected-to host. header is a Hash like { 'Accept' => '/', … }.

This method returns a Net::HTTPResponse object.

This method never raises an exception.

response = nil
Net::HTTP.start('some.www.server', 80) {|http|
  response = http.head('/index.html')
}
p response['content-type']

# File lib/net/http.rb, line 1146
def head(path, initheader = nil)
  request(Head.new(path, initheader))
end
head2(path, initheader = nil, &block) click to toggle source
Alias for: request_head
inspect() click to toggle source
# File lib/net/http.rb, line 665
def inspect
  "#<#{self.class} #{@address}:#{@port} open=#{started?}>"
end
lock(path, body, initheader = nil) click to toggle source

Sends a LOCK request to the path and gets a response, as an HTTPResponse object.

# File lib/net/http.rb, line 1200
def lock(path, body, initheader = nil)
  request(Lock.new(path, initheader), body)
end
mkcol(path, body = nil, initheader = nil) click to toggle source

Sends a MKCOL request to the path and gets a response, as an HTTPResponse object.

# File lib/net/http.rb, line 1242
def mkcol(path, body = nil, initheader = nil)
  request(Mkcol.new(path, initheader), body)
end
move(path, initheader = nil) click to toggle source

Sends a MOVE request to the path and gets a response, as an HTTPResponse object.

# File lib/net/http.rb, line 1230
def move(path, initheader = nil)
  request(Move.new(path, initheader))
end
options(path, initheader = nil) click to toggle source

Sends a OPTIONS request to the path and gets a response, as an HTTPResponse object.

# File lib/net/http.rb, line 1212
def options(path, initheader = nil)
  request(Options.new(path, initheader))
end
patch(path, data, initheader = nil, dest = nil) { |body_segment| ... } click to toggle source

Sends a PATCH request to the path and gets a response, as an HTTPResponse object.

# File lib/net/http.rb, line 1184
def patch(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
  send_entity(path, data, initheader, dest, Patch, &block)
end
peer_cert() click to toggle source

Returns the X.509 certificates the server presented.

# File lib/net/http.rb, line 831
def peer_cert
  if not use_ssl? or not @socket
    return nil
  end
  @socket.io.peer_cert
end
post(path, data, initheader = nil, dest = nil) { |body_segment| ... } click to toggle source

Posts data (must be a String) to path. header must be a Hash like { 'Accept' => '/', … }.

This method returns a Net::HTTPResponse object.

If called with a block, yields each fragment of the entity body in turn as a string as it is read from the socket. Note that in this case, the returned response object will not contain a (meaningful) body.

dest argument is obsolete. It still works but you must not use it.

This method never raises exception.

response = http.post('/cgi-bin/search.rb', 'query=foo')

# using block
File.open('result.txt', 'w') {|f|
  http.post('/cgi-bin/search.rb', 'query=foo') do |str|
    f.write str
  end
}

You should set Content-Type: header field for POST. If no Content-Type: field given, this method uses “application/x-www-form-urlencoded” by default.

# File lib/net/http.rb, line 1178
def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
  send_entity(path, data, initheader, dest, Post, &block)
end
post2(path, data, initheader = nil) click to toggle source
Alias for: request_post
propfind(path, body = nil, initheader = {'Depth' => '0'}) click to toggle source

Sends a PROPFIND request to the path and gets a response, as an HTTPResponse object.

# File lib/net/http.rb, line 1218
def propfind(path, body = nil, initheader = {'Depth' => '0'})
  request(Propfind.new(path, initheader), body)
end
proppatch(path, body, initheader = nil) click to toggle source

Sends a PROPPATCH request to the path and gets a response, as an HTTPResponse object.

# File lib/net/http.rb, line 1194
def proppatch(path, body, initheader = nil)
  request(Proppatch.new(path, initheader), body)
end
proxy?() click to toggle source

True if requests for this connection will be proxied

# File lib/net/http.rb, line 1012
def proxy?
  !!if @proxy_from_env then
    proxy_uri
  else
    @proxy_address
  end
end
proxy_address() click to toggle source

The address of the proxy server, if one is configured.

# File lib/net/http.rb, line 1031
def proxy_address
  if @proxy_from_env then
    proxy_uri && proxy_uri.hostname
  else
    @proxy_address
  end
end
Also aliased as: proxyaddr
proxy_from_env?() click to toggle source

True if the proxy for this connection is determined from the environment

# File lib/net/http.rb, line 1021
def proxy_from_env?
  @proxy_from_env
end
proxy_pass() click to toggle source

The proxy password, if one is configured

# File lib/net/http.rb, line 1054
def proxy_pass
  @proxy_pass
end
proxy_port() click to toggle source

The port of the proxy server, if one is configured.

# File lib/net/http.rb, line 1040
def proxy_port
  if @proxy_from_env then
    proxy_uri && proxy_uri.port
  else
    @proxy_port
  end
end
Also aliased as: proxyport
proxy_user() click to toggle source

The proxy username, if one is configured

# File lib/net/http.rb, line 1049
def proxy_user
  @proxy_user
end
proxyaddr() click to toggle source
Alias for: proxy_address
proxyport() click to toggle source
Alias for: proxy_port
read_timeout=(sec) click to toggle source

Setter for the #read_timeout attribute.

# File lib/net/http.rb, line 714
def read_timeout=(sec)
  @socket.read_timeout = sec if @socket
  @read_timeout = sec
end
request(req, body = nil) { |response| ... } click to toggle source

Sends an HTTPRequest object req to the HTTP server.

If req is a Net::HTTP::Post or Net::HTTP::Put request containing data, the data is also sent. Providing data for a Net::HTTP::Head or Net::HTTP::Get request results in an ArgumentError.

Returns an HTTPResponse object.

When called with a block, passes an HTTPResponse object to the block. The body of the response will not have been read yet; the block can process it using Net::HTTPResponse#read_body, if desired.

This method never raises Net::* exceptions.

# File lib/net/http.rb, line 1365
def request(req, body = nil, &block)  # :yield: +response+
  unless started?
    start {
      req['connection'] ||= 'close'
      return request(req, body, &block)
    }
  end
  if proxy_user()
    req.proxy_basic_auth proxy_user(), proxy_pass() unless use_ssl?
  end
  req.set_body_internal body
  res = transport_request(req, &block)
  if sspi_auth?(res)
    sspi_auth(req)
    res = transport_request(req, &block)
  end
  res
end
request_get(path, initheader = nil) { |response| ... } click to toggle source

Sends a GET request to the path. Returns the response as a Net::HTTPResponse object.

When called with a block, passes an HTTPResponse object to the block. The body of the response will not have been read yet; the block can process it using Net::HTTPResponse#read_body, if desired.

Returns the response.

This method never raises Net::* exceptions.

response = http.request_get('/index.html')
# The entity body is already read in this case.
p response['content-type']
puts response.body

# Using a block
http.request_get('/index.html') {|response|
  p response['content-type']
  response.read_body do |str|   # read body now
    print str
  end
}

# File lib/net/http.rb, line 1277
def request_get(path, initheader = nil, &block) # :yield: +response+
  request(Get.new(path, initheader), &block)
end
Also aliased as: get2
request_head(path, initheader = nil, &block) click to toggle source

Sends a HEAD request to the path and returns the response as a Net::HTTPResponse object.

Returns the response.

This method never raises Net::* exceptions.

response = http.request_head('/index.html')
p response['content-type']
# File lib/net/http.rb, line 1291
def request_head(path, initheader = nil, &block)
  request(Head.new(path, initheader), &block)
end
Also aliased as: head2
request_post(path, data, initheader = nil) { |response| ... } click to toggle source

Sends a POST request to the path.

Returns the response as a Net::HTTPResponse object.

When called with a block, the block is passed an HTTPResponse object. The body of that response will not have been read yet; the block can process it using Net::HTTPResponse#read_body, if desired.

Returns the response.

This method never raises Net::* exceptions.

# example
response = http.request_post('/cgi-bin/nice.rb', 'datadatadata...')
p response.status
puts response.body          # body is already read in this case

# using block
http.request_post('/cgi-bin/nice.rb', 'datadatadata...') {|response|
  p response.status
  p response['content-type']
  response.read_body do |str|   # read body now
    print str
  end
}

# File lib/net/http.rb, line 1321
def request_post(path, data, initheader = nil, &block) # :yield: +response+
  request Post.new(path, initheader), data, &block
end
Also aliased as: post2
send_request(name, path, data = nil, header = nil) click to toggle source

Sends an HTTP request to the HTTP server. Also sends a DATA string if data is given.

Returns a Net::HTTPResponse object.

This method never raises Net::* exceptions.

response = http.send_request('GET', '/index.html')
puts response.body
# File lib/net/http.rb, line 1345
def send_request(name, path, data = nil, header = nil)
  r = HTTPGenericRequest.new(name,(data ? true : false),true,path,header)
  request r, data
end
set_debug_output(output) click to toggle source

WARNING This method opens a serious security hole. Never use this method in production code.

Sets an output stream for debugging.

http = Net::HTTP.new
http.set_debug_output $stderr
http.start { .... }
# File lib/net/http.rb, line 678
def set_debug_output(output)
  warn 'Net::HTTP#set_debug_output called after HTTP started' if started?
  @debug_output = output
end
start() { |http| ... } click to toggle source

Opens a TCP connection and HTTP session.

When this method is called with a block, it passes the Net::HTTP object to the block, and closes the TCP connection and HTTP session after the block has been executed.

When called with a block, it returns the return value of the block; otherwise, it returns self.

# File lib/net/http.rb, line 847
def start  # :yield: http
  raise IOError, 'HTTP session already opened' if @started
  if block_given?
    begin
      do_start
      return yield(self)
    ensure
      do_finish
    end
  end
  do_start
  self
end
started?() click to toggle source

Returns true if the HTTP session has been started.

# File lib/net/http.rb, line 737
def started?
  @started
end
Also aliased as: active?
trace(path, initheader = nil) click to toggle source

Sends a TRACE request to the path and gets a response, as an HTTPResponse object.

# File lib/net/http.rb, line 1248
def trace(path, initheader = nil)
  request(Trace.new(path, initheader))
end
unlock(path, body, initheader = nil) click to toggle source

Sends a UNLOCK request to the path and gets a response, as an HTTPResponse object.

# File lib/net/http.rb, line 1206
def unlock(path, body, initheader = nil)
  request(Unlock.new(path, initheader), body)
end
use_ssl=(flag) click to toggle source

Turn on/off SSL. This flag must be set before starting session. If you change use_ssl value after session started, a Net::HTTP object raises IOError.

# File lib/net/http.rb, line 754
def use_ssl=(flag)
  flag = flag ? true : false
  if started? and @use_ssl != flag
    raise IOError, "use_ssl value changed, but session already started"
  end
  @use_ssl = flag
end
use_ssl?() click to toggle source

Returns true if SSL/TLS is being used with HTTP.

# File lib/net/http.rb, line 746
def use_ssl?
  @use_ssl
end


class Net::HTTP::Copy - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Copy

See Net::HTTPGenericRequest for attributes and methods.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Delete - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Delete

See Net::HTTPGenericRequest for attributes and methods. See Net::HTTP for usage examples.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Get - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Get

See Net::HTTPGenericRequest for attributes and methods. See Net::HTTP for usage examples.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Head - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Head

See Net::HTTPGenericRequest for attributes and methods. See Net::HTTP for usage examples.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Lock - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Lock

See Net::HTTPGenericRequest for attributes and methods.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Mkcol - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Mkcol

See Net::HTTPGenericRequest for attributes and methods.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Move - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Move

See Net::HTTPGenericRequest for attributes and methods.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Options - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Options

See Net::HTTPGenericRequest for attributes and methods.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Patch - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Patch

See Net::HTTPGenericRequest for attributes and methods.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Post - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Post

See Net::HTTPGenericRequest for attributes and methods. See Net::HTTP for usage examples.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Propfind - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Propfind

See Net::HTTPGenericRequest for attributes and methods.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Proppatch - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Proppatch

See Net::HTTPGenericRequest for attributes and methods.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Put - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Put

See Net::HTTPGenericRequest for attributes and methods. See Net::HTTP for usage examples.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Trace - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Trace

See Net::HTTPGenericRequest for attributes and methods.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTP::Unlock - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTP::Unlock

See Net::HTTPGenericRequest for attributes and methods.

In Files

  • lib/net/http/requests.rb

Parent

Net::HTTPRequest

Constants

METHOD
REQUEST_HAS_BODY
RESPONSE_HAS_BODY


class Net::HTTPAccepted - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPAccepted

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPSuccess

Constants

HAS_BODY


class Net::HTTPBadGateway - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPBadGateway

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPServerError

Constants

HAS_BODY


class Net::HTTPBadRequest - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPBadRequest

308 Permanent Redirect - in draft

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPBadResponse - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPBadResponse

In Files

  • lib/net/http.rb

Parent

StandardError


class Net::HTTPClientError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPClientError

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPResponse

Constants

EXCEPTION_TYPE
HAS_BODY


class Net::HTTPConflict - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPConflict

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPContinue - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPContinue

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPInformation

Constants

HAS_BODY


class Net::HTTPCreated - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPCreated

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPSuccess

Constants

HAS_BODY


class Net::HTTPUnknownResponse::EXCEPTION_TYPE - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPUnknownResponse::EXCEPTION_TYPE

In Files

  • lib/net/http/exceptions.rb

Parent

Net::ProtocolError

Included Modules

  • Net::HTTPExceptions


module Net::HTTPExceptions - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Net::HTTPExceptions

Net::HTTP exception class. You cannot use Net::HTTPExceptions directly; instead, you must use its subclasses.

In Files

  • lib/net/http/exceptions.rb

Attributes

data[R]
response[R]


class Net::HTTPExpectationFailed - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPExpectationFailed

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPFailedDependency - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPFailedDependency

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPFatalError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPFatalError

In Files

  • lib/net/http/exceptions.rb

Parent

Net::ProtoFatalError

Included Modules

  • Net::HTTPExceptions


class Net::HTTPForbidden - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPForbidden

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPFound - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPFound

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPRedirection

Constants

HAS_BODY


class Net::HTTPGatewayTimeOut - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPGatewayTimeOut

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPServerError

Constants

HAS_BODY


class Net::HTTPGenericRequest - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPGenericRequest

HTTPGenericRequest is the parent of the HTTPRequest class. Do not use this directly; use a subclass of HTTPRequest.

Mixes in the HTTPHeader module to provide easier access to HTTP headers.

In Files

  • lib/net/http/generic_request.rb

Parent

Object

Included Modules

  • Net::HTTPHeader

Attributes

body[R]
body_stream[R]
decode_content[R]

Automatically set to false if the user sets the Accept-Encoding header. This indicates they wish to handle Content-encoding in responses themselves.

method[R]
path[R]
uri[R]

Public Class Methods

new(m, reqbody, resbody, uri_or_path, initheader = nil) click to toggle source
# File lib/net/http/generic_request.rb, line 10
def initialize(m, reqbody, resbody, uri_or_path, initheader = nil)
  @method = m
  @request_has_body = reqbody
  @response_has_body = resbody

  if URI === uri_or_path then
    @uri = uri_or_path.dup
    host = @uri.hostname
    host += ":#{@uri.port}" if @uri.port != @uri.class::DEFAULT_PORT
    path = uri_or_path.request_uri
  else
    @uri = nil
    host = nil
    path = uri_or_path
  end

  raise ArgumentError, "no HTTP request path given" unless path
  raise ArgumentError, "HTTP request path is empty" if path.empty?
  @path = path

  @decode_content = false

  if @response_has_body and Net::HTTP::HAVE_ZLIB then
    if !initheader ||
       !initheader.keys.any? { |k|
         %w[accept-encoding range].include? k.downcase
       } then
      @decode_content = true
      initheader = initheader ? initheader.dup : {}
      initheader["accept-encoding"] =
        "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
    end
  end

  initialize_http_header initheader
  self['Accept'] ||= '*/*'
  self['User-Agent'] ||= 'Ruby'
  self['Host'] ||= host
  @body = nil
  @body_stream = nil
  @body_data = nil
end

Public Instance Methods

body=(str) click to toggle source
# File lib/net/http/generic_request.rb, line 91
def body=(str)
  @body = str
  @body_stream = nil
  @body_data = nil
  str
end
body_exist?() click to toggle source
# File lib/net/http/generic_request.rb, line 84
def body_exist?
  warn "Net::HTTPRequest#body_exist? is obsolete; use response_body_permitted?" if $VERBOSE
  response_body_permitted?
end
body_stream=(input) click to toggle source
# File lib/net/http/generic_request.rb, line 100
def body_stream=(input)
  @body = nil
  @body_stream = input
  @body_data = nil
  input
end
inspect() click to toggle source
# File lib/net/http/generic_request.rb, line 62
def inspect
  "\#<#{self.class} #{@method}>"
end
request_body_permitted?() click to toggle source
# File lib/net/http/generic_request.rb, line 76
def request_body_permitted?
  @request_has_body
end
response_body_permitted?() click to toggle source
# File lib/net/http/generic_request.rb, line 80
def response_body_permitted?
  @response_has_body
end


class Net::HTTPGone - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPGone

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


module Net::HTTPHeader - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Net::HTTPHeader

The HTTPHeader module defines methods for reading and writing HTTP headers.

It is used as a mixin by other classes, to provide hash-like access to HTTP header values. Unlike raw hash access, HTTPHeader provides access via case-insensitive keys. It also provides methods for accessing commonly-used HTTP header values in more convenient formats.

In Files

  • lib/net/http/header.rb

Public Instance Methods

[](key) click to toggle source

Returns the header field corresponding to the case-insensitive key. For example, a key of “Content-Type” might return “text/html”

# File lib/net/http/header.rb, line 29
def [](key)
  a = @header[key.downcase] or return nil
  a.join(', ')
end
[]=(key, val) click to toggle source

Sets the header field corresponding to the case-insensitive key.

# File lib/net/http/header.rb, line 35
def []=(key, val)
  unless val
    @header.delete key.downcase
    return val
  end
  @header[key.downcase] = [val]
end
add_field(key, val) click to toggle source
Ruby 1.8.3

Adds a value to a named header field, instead of replacing its value. Second argument val must be a String. See also #[]=, #[] and get_fields.

request.add_field 'X-My-Header', 'a'
p request['X-My-Header']              #=> "a"
p request.get_fields('X-My-Header')   #=> ["a"]
request.add_field 'X-My-Header', 'b'
p request['X-My-Header']              #=> "a, b"
p request.get_fields('X-My-Header')   #=> ["a", "b"]
request.add_field 'X-My-Header', 'c'
p request['X-My-Header']              #=> "a, b, c"
p request.get_fields('X-My-Header')   #=> ["a", "b", "c"]

# File lib/net/http/header.rb, line 58
def add_field(key, val)
  if @header.key?(key.downcase)
    @header[key.downcase].push val
  else
    @header[key.downcase] = [val]
  end
end
basic_auth(account, password) click to toggle source

Set the Authorization: header for “Basic” authorization.

# File lib/net/http/header.rb, line 419
def basic_auth(account, password)
  @header['authorization'] = [basic_encode(account, password)]
end
canonical_each() click to toggle source
Alias for: each_capitalized
chunked?() click to toggle source

Returns “true” if the “transfer-encoding” header is present and set to “chunked”. This is an HTTP/1.1 feature, allowing the the content to be sent in “chunks” without at the outset stating the entire content length.

# File lib/net/http/header.rb, line 280
def chunked?
  return false unless @header['transfer-encoding']
  field = self['Transfer-Encoding']
  (/(?:\A|[^\-\w])chunked(?![\-\w])/ =~ field) ? true : false
end
connection_close?() click to toggle source
# File lib/net/http/header.rb, line 433
def connection_close?
  tokens(@header['connection']).include?('close') or
  tokens(@header['proxy-connection']).include?('close')
end
connection_keep_alive?() click to toggle source
# File lib/net/http/header.rb, line 438
def connection_keep_alive?
  tokens(@header['connection']).include?('keep-alive') or
  tokens(@header['proxy-connection']).include?('keep-alive')
end
content_length() click to toggle source

Returns an Integer object which represents the HTTP Content-Length: header field, or nil if that field was not provided.

# File lib/net/http/header.rb, line 261
def content_length
  return nil unless key?('Content-Length')
  len = self['Content-Length'].slice(/\d+/) or
      raise Net::HTTPHeaderSyntaxError, 'wrong Content-Length format'
  len.to_i
end
content_length=(len) click to toggle source
# File lib/net/http/header.rb, line 268
def content_length=(len)
  unless len
    @header.delete 'content-length'
    return nil
  end
  @header['content-length'] = [len.to_i.to_s]
end
content_range() click to toggle source

Returns a Range object which represents the value of the Content-Range: header field. For a partial entity body, this indicates where this fragment fits inside the full entity body, as range of byte offsets.

# File lib/net/http/header.rb, line 290
def content_range
  return nil unless @header['content-range']
  m = %r<bytes\s+(\d+)-(\d+)/(\d+|\*)>.match(self['Content-Range']) or
      raise Net::HTTPHeaderSyntaxError, 'wrong Content-Range format'
  m[1].to_i .. m[2].to_i
end
content_type() click to toggle source

Returns a content type string such as “text/html”. This method returns nil if Content-Type: header field does not exist.

# File lib/net/http/header.rb, line 305
def content_type
  return nil unless main_type()
  if sub_type()
  then "#{main_type()}/#{sub_type()}"
  else main_type()
  end
end
content_type=(type, params = {}) click to toggle source
Alias for: set_content_type
delete(key) click to toggle source

Removes a header field, specified by case-insensitive key.

# File lib/net/http/header.rb, line 139
def delete(key)
  @header.delete(key.downcase)
end
each() click to toggle source
Alias for: each_header
each_capitalized() { |capitalize(k), join(', ')| ... } click to toggle source

As for each_header, except the keys are provided in capitalized form.

Note that header names are capitalized systematically; capitalization may not match that used by the remote HTTP server in its response.

# File lib/net/http/header.rb, line 162
def each_capitalized
  block_given? or return enum_for(__method__)
  @header.each do |k,v|
    yield capitalize(k), v.join(', ')
  end
end
Also aliased as: canonical_each
each_capitalized_name() { |key| ... } click to toggle source

Iterates through the header names in the header, passing capitalized header names to the code block.

Note that header names are capitalized systematically; capitalization may not match that used by the remote HTTP server in its response.

# File lib/net/http/header.rb, line 122
def each_capitalized_name  #:yield: +key+
  block_given? or return enum_for(__method__)
  @header.each_key do |k|
    yield capitalize(k)
  end
end
each_header() { |key| ... } click to toggle source

Iterates through the header names and values, passing in the name and value to the code block supplied.

Example:

response.header.each_header {|key,value| puts "#{key} = #{value}" }

# File lib/net/http/header.rb, line 98
def each_header   #:yield: +key+, +value+
  block_given? or return enum_for(__method__)
  @header.each do |k,va|
    yield k, va.join(', ')
  end
end
Also aliased as: each
each_key() click to toggle source
Alias for: each_name
each_name() { |key| ... } click to toggle source

Iterates through the header names in the header, passing each header name to the code block.

# File lib/net/http/header.rb, line 109
def each_name(&block)   #:yield: +key+
  block_given? or return enum_for(__method__)
  @header.each_key(&block)
end
Also aliased as: each_key
each_value() { |value| ... } click to toggle source

Iterates through header values, passing each value to the code block.

# File lib/net/http/header.rb, line 131
def each_value   #:yield: +value+
  block_given? or return enum_for(__method__)
  @header.each_value do |va|
    yield va.join(', ')
  end
end
fetch(key, *args) { |key| ... } click to toggle source

Returns the header field corresponding to the case-insensitive key. Returns the default value args, or the result of the block, or raises an IndexError if there's no header field named key See Hash#fetch

# File lib/net/http/header.rb, line 86
def fetch(key, *args, &block)   #:yield: +key+
  a = @header.fetch(key.downcase, *args, &block)
  a.kind_of?(Array) ? a.join(', ') : a
end
form_data=(params, sep = '&') click to toggle source
Alias for: set_form_data
get_fields(key) click to toggle source
Ruby 1.8.3

Returns an array of header field strings corresponding to the case-insensitive key. This method allows you to get duplicated header fields without any processing. See also #[].

p response.get_fields('Set-Cookie')
  #=> ["session=al98axx; expires=Fri, 31-Dec-1999 23:58:23",
       "query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"]
p response['Set-Cookie']
  #=> "session=al98axx; expires=Fri, 31-Dec-1999 23:58:23, query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"

# File lib/net/http/header.rb, line 77
def get_fields(key)
  return nil unless @header[key.downcase]
  @header[key.downcase].dup
end
initialize_http_header(initheader) click to toggle source
# File lib/net/http/header.rb, line 12
def initialize_http_header(initheader)
  @header = {}
  return unless initheader
  initheader.each do |key, value|
    warn "net/http: warning: duplicated HTTP header: #{key}" if key?(key) and $VERBOSE
    @header[key.downcase] = [value.strip]
  end
end
key?(key) click to toggle source

true if key header exists.

# File lib/net/http/header.rb, line 144
def key?(key)
  @header.key?(key.downcase)
end
main_type() click to toggle source

Returns a content type string such as “text”. This method returns nil if Content-Type: header field does not exist.

# File lib/net/http/header.rb, line 315
def main_type
  return nil unless @header['content-type']
  self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip
end
proxy_basic_auth(account, password) click to toggle source

Set Proxy-Authorization: header for “Basic” authorization.

# File lib/net/http/header.rb, line 424
def proxy_basic_auth(account, password)
  @header['proxy-authorization'] = [basic_encode(account, password)]
end
range() click to toggle source

Returns an Array of Range objects which represent the Range: HTTP header field, or nil if there is no such header.

# File lib/net/http/header.rb, line 178
def range
  return nil unless @header['range']

  value = self['Range']
  # byte-range-set = *( "," OWS ) ( byte-range-spec / suffix-byte-range-spec )
  #   *( OWS "," [ OWS ( byte-range-spec / suffix-byte-range-spec ) ] )
  # corrected collected ABNF
  # http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-19#section-5.4.1
  # http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-19#appendix-C
  # http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-19#section-3.2.5
  unless /\Abytes=((?:,[ \t]*)*(?:\d+-\d*|-\d+)(?:[ \t]*,(?:[ \t]*\d+-\d*|-\d+)?)*)\z/ =~ value
    raise Net::HTTPHeaderSyntaxError, "invalid syntax for byte-ranges-specifier: '#{value}'"
  end

  byte_range_set = $1
  result = byte_range_set.split(/,/).map {|spec|
    m = /(\d+)?\s*-\s*(\d+)?/.match(spec) or
            raise Net::HTTPHeaderSyntaxError, "invalid byte-range-spec: '#{spec}'"
    d1 = m[1].to_i
    d2 = m[2].to_i
    if m[1] and m[2]
      if d1 > d2
        raise Net::HTTPHeaderSyntaxError, "last-byte-pos MUST greater than or equal to first-byte-pos but '#{spec}'"
      end
      d1..d2
    elsif m[1]
      d1..-1
    elsif m[2]
      -d2..-1
    else
      raise Net::HTTPHeaderSyntaxError, 'range is not specified'
    end
  }
  # if result.empty?
  # byte-range-set must include at least one byte-range-spec or suffix-byte-range-spec
  # but above regexp already denies it.
  if result.size == 1 && result[0].begin == 0 && result[0].end == -1
    raise Net::HTTPHeaderSyntaxError, 'only one suffix-byte-range-spec with zero suffix-length'
  end
  result
end
range=(r, e = nil) click to toggle source
Alias for: set_range
range_length() click to toggle source

The length of the range represented in Content-Range: header.

# File lib/net/http/header.rb, line 298
def range_length
  r = content_range() or return nil
  r.end - r.begin + 1
end
set_content_type(type, params = {}) click to toggle source

Sets the content type in an HTTP header. The type should be a full HTTP content type, e.g. “text/html”. The params are an optional Hash of parameters to add after the content type, e.g. {'charset' => 'iso-8859-1'}

# File lib/net/http/header.rb, line 348
def set_content_type(type, params = {})
  @header['content-type'] = [type + params.map{|k,v|"; #{k}=#{v}"}.join('')]
end
Also aliased as: content_type=
set_form(params, enctype='application/x-www-form-urlencoded', formopt={}) click to toggle source

Set a HTML form data set. params is the form data set; it is an Array of Arrays or a Hash +enctype is the type to encode the form data set. It is application/x-www-form-urlencoded or multipart/form-data. formpot is an optional hash to specify the detail.

boundary

the boundary of the multipart message

charset

the charset of the message. All names and the values of non-file fields are encoded as the charset.

Each item of params is an array and contains following items:

name

the name of the field

value

the value of the field, it should be a String or a File

opt

an optional hash to specify additional information

Each item is a file field or a normal field. If value is a File object or the opt have a filename key, the item is treated as a file field.

If Transfer-Encoding is set as chunked, this send the request in chunked encoding. Because chunked encoding is HTTP/1.1 feature, you must confirm the server to support HTTP/1.1 before sending it.

Example:

http.set_form([["q", "ruby"], ["lang", "en"]])

See also RFC 2388, RFC 2616, HTML 4.01, and HTML5

# File lib/net/http/header.rb, line 404
def set_form(params, enctype='application/x-www-form-urlencoded', formopt={})
  @body_data = params
  @body = nil
  @body_stream = nil
  @form_option = formopt
  case enctype
  when /\Aapplication\/x-www-form-urlencoded\z/,
    /\Amultipart\/form-data\z/
    self.content_type = enctype
  else
    raise ArgumentError, "invalid enctype: #{enctype}"
  end
end
set_form_data(params, sep = '&') click to toggle source

Set header fields and a body from HTML form data. params should be an Array of Arrays or a Hash containing HTML form data. Optional argument sep means data record separator.

Values are URL encoded as necessary and the content-type is set to application/x-www-form-urlencoded

Example:

http.form_data = {"q" => "ruby", "lang" => "en"}
http.form_data = {"q" => ["ruby", "perl"], "lang" => "en"}
http.set_form_data({"q" => "ruby", "lang" => "en"}, ';')

# File lib/net/http/header.rb, line 367
def set_form_data(params, sep = '&')
  query = URI.encode_www_form(params)
  query.gsub!(/&/, sep) if sep != '&'
  self.body = query
  self.content_type = 'application/x-www-form-urlencoded'
end
Also aliased as: form_data=
set_range(r, e = nil) click to toggle source

Sets the HTTP Range: header. Accepts either a Range object as a single argument, or a beginning index and a length from that index. Example:

req.range = (0..1023)
req.set_range 0, 1023
# File lib/net/http/header.rb, line 228
def set_range(r, e = nil)
  unless r
    @header.delete 'range'
    return r
  end
  r = (r...r+e) if e
  case r
  when Numeric
    n = r.to_i
    rangestr = (n > 0 ? "0-#{n-1}" : "-#{-n}")
  when Range
    first = r.first
    last = r.last
    last -= 1 if r.exclude_end?
    if last == -1
      rangestr = (first > 0 ? "#{first}-" : "-#{-first}")
    else
      raise Net::HTTPHeaderSyntaxError, 'range.first is negative' if first < 0
      raise Net::HTTPHeaderSyntaxError, 'range.last is negative' if last < 0
      raise Net::HTTPHeaderSyntaxError, 'must be .first < .last' if first > last
      rangestr = "#{first}-#{last}"
    end
  else
    raise TypeError, 'Range/Integer is required'
  end
  @header['range'] = ["bytes=#{rangestr}"]
  r
end
Also aliased as: range=
sub_type() click to toggle source

Returns a content type string such as “html”. This method returns nil if Content-Type: header field does not exist or sub-type is not given (e.g. “Content-Type: text”).

# File lib/net/http/header.rb, line 323
def sub_type
  return nil unless @header['content-type']
  _, sub = *self['Content-Type'].split(';').first.to_s.split('/')
  return nil unless sub
  sub.strip
end
to_hash() click to toggle source

Returns a Hash consisting of header names and values. e.g. {“cache-control” => “private”,

"content-type" => "text/html",
"date" => "Wed, 22 Jun 2005 22:11:50 GMT"}

# File lib/net/http/header.rb, line 153
def to_hash
  @header.dup
end
type_params() click to toggle source

Any parameters specified for the content type, returned as a Hash. For example, a header of Content-Type: text/html; charset=EUC-JP would result in #type_params returning {'charset' => 'EUC-JP'}

# File lib/net/http/header.rb, line 333
def type_params
  result = {}
  list = self['Content-Type'].to_s.split(';')
  list.shift
  list.each do |param|
    k, v = *param.split('=', 2)
    result[k.strip] = v.strip
  end
  result
end


class Net::HTTPHeaderSyntaxError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPHeaderSyntaxError

In Files

  • lib/net/http.rb

Parent

StandardError


class Net::HTTPInformation - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPInformation

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPResponse

Constants

EXCEPTION_TYPE
HAS_BODY


class Net::HTTPInsufficientStorage - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPInsufficientStorage

506 Variant Also Negotiates - RFC 2295; experimental

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPServerError

Constants

HAS_BODY


class Net::HTTPInternalServerError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPInternalServerError

444 No Response - Nginx 449 Retry With - Microsoft 450 Blocked by Windows Parental Controls - Microsoft 499 Client Closed Request - Nginx

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPServerError

Constants

HAS_BODY


class Net::HTTPLengthRequired - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPLengthRequired

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPLocked - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPLocked

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPMethodNotAllowed - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPMethodNotAllowed

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPMovedPermanently - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPMovedPermanently

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPRedirection

Constants

HAS_BODY


class Net::HTTPMultiStatus - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPMultiStatus

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPSuccess

Constants

HAS_BODY


class Net::HTTPMultipleChoices - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPMultipleChoices

208 Already Reported - RFC 5842; experimental 226 IM Used - RFC 3229; no famous implementation known

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPRedirection

Constants

HAS_BODY


class Net::HTTPNetworkAuthenticationRequired - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPNetworkAuthenticationRequired

508 Loop Detected - RFC 5842; experimental 509 Bandwidth Limit Exceeded - Apache bw/limited extension 510 Not Extended - RFC 2774; experimental

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPServerError

Constants

HAS_BODY


class Net::HTTPNoContent - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPNoContent

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPSuccess

Constants

HAS_BODY


class Net::HTTPNonAuthoritativeInformation - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPNonAuthoritativeInformation

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPSuccess

Constants

HAS_BODY


class Net::HTTPNotAcceptable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPNotAcceptable

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPNotFound - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPNotFound

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPNotImplemented - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPNotImplemented

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPServerError

Constants

HAS_BODY


class Net::HTTPNotModified - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPNotModified

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPRedirection

Constants

HAS_BODY


class Net::HTTPOK - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPOK

102 - RFC 2518; removed in RFC 4918

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPSuccess

Constants

HAS_BODY


class Net::HTTPPartialContent - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPPartialContent

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPSuccess

Constants

HAS_BODY


class Net::HTTPPaymentRequired - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPPaymentRequired

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPPreconditionFailed - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPPreconditionFailed

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPPreconditionRequired - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPPreconditionRequired

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPProxyAuthenticationRequired - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPProxyAuthenticationRequired

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPRedirection - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPRedirection

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPResponse

Constants

EXCEPTION_TYPE
HAS_BODY


class Net::HTTPRetriableError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPRetriableError

In Files

  • lib/net/http/exceptions.rb

Parent

Net::ProtoRetriableError

Included Modules

  • Net::HTTPExceptions


class Net::HTTPRequest - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPRequest

HTTP request class. This class wraps together the request header and the request path. You cannot use this class directly. Instead, you should use one of its subclasses: Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Head.

In Files

  • lib/net/http/request.rb

Parent

Net::HTTPGenericRequest

Public Class Methods

new(path, initheader = nil) click to toggle source

Creates an HTTP request object for path.

initheader are the default headers to use. Net::HTTP adds Accept-Encoding to enable compression of the response body unless Accept-Encoding or Range are supplied in initheader.

# File lib/net/http/request.rb, line 13
def initialize(path, initheader = nil)
  super self.class::METHOD,
        self.class::REQUEST_HAS_BODY,
        self.class::RESPONSE_HAS_BODY,
        path, initheader
end


class Net::HTTPRequestEntityTooLarge - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPRequestEntityTooLarge

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPRequestHeaderFieldsTooLarge - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPRequestHeaderFieldsTooLarge

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPRequestTimeOut - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPRequestTimeOut

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPRequestURITooLong - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPRequestURITooLong

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPRequestedRangeNotSatisfiable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPRequestedRangeNotSatisfiable

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPResetContent - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPResetContent

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPSuccess

Constants

HAS_BODY


class Net::HTTPResponse - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPResponse

HTTP response class.

This class wraps together the response header and the response body (the entity requested).

It mixes in the HTTPHeader module, which provides access to response header values both via hash-like methods and via individual readers.

Note that each possible HTTP response code defines its own HTTPResponse subclass. These are listed below.

All classes are defined under the Net module. Indentation indicates inheritance. For a list of the classes see Net::HTTP.

In Files

  • lib/net/http/response.rb
  • lib/net/http/responses.rb

Parent

Object

Included Modules

  • Net::HTTPHeader

Constants

CODE_CLASS_TO_OBJ
CODE_TO_OBJ

Attributes

code[R]

The HTTP result code string. For example, '302'. You can also determine the response type by examining which response subclass the response object is an instance of.

decode_content[RW]

Set to true automatically when the request did not contain an Accept-Encoding header from the user.

http_version[R]

The HTTP version supported by the server.

message[R]

The HTTP result message sent by the server. For example, 'Not Found'.

msg[R]

The HTTP result message sent by the server. For example, 'Not Found'.

uri[R]

The URI used to fetch this response. The response URI is only available if a URI was used to create the request.

Public Class Methods

body_permitted?() click to toggle source

true if the response has a body.

# File lib/net/http/response.rb, line 19
def body_permitted?
  self::HAS_BODY
end

Public Instance Methods

body() click to toggle source

Returns the full entity body.

Calling this method a second or subsequent time will return the string already read.

http.request_get('/index.html') {|res|
  puts res.body
}

http.request_get('/index.html') {|res|
  p res.body.object_id   # 538149362
  p res.body.object_id   # 538149362
}

# File lib/net/http/response.rb, line 225
def body
  read_body()
end
Also aliased as: entity
body=(value) click to toggle source

Because it may be necessary to modify the body, Eg, decompression this method facilitates that.

# File lib/net/http/response.rb, line 231
def body=(value)
  @body = value
end
entity() click to toggle source
Alias for: body
inspect() click to toggle source
# File lib/net/http/response.rb, line 106
def inspect
  "#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
end
read_body(dest = nil, &block) click to toggle source

Gets the entity body returned by the remote HTTP server.

If a block is given, the body is passed to the block, and the body is provided in fragments, as it is read in from the socket.

Calling this method a second or subsequent time for the same HTTPResponse object will return the value already read.

http.request_get('/index.html') {|res|
  puts res.read_body
}

http.request_get('/index.html') {|res|
  p res.read_body.object_id   # 538149362
  p res.read_body.object_id   # 538149362
}

# using iterator
http.request_get('/index.html') {|res|
  res.read_body do |segment|
    print segment
  end
}

# File lib/net/http/response.rb, line 193
def read_body(dest = nil, &block)
  if @read
    raise IOError, "#{self.class}\#read_body called twice" if dest or block
    return @body
  end
  to = procdest(dest, block)
  stream_check
  if @body_exist
    read_body_0 to
    @body = to
  else
    @body = nil
  end
  @read = true

  @body
end
value() click to toggle source

Raises an HTTP error if the response is not 2xx (success).

# File lib/net/http/response.rb, line 127
def value
  error! unless self.kind_of?(Net::HTTPSuccess)
end


class Net::HTTPSeeOther - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPSeeOther

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPRedirection

Constants

HAS_BODY


class Net::HTTPServerError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPServerError

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPResponse

Constants

EXCEPTION_TYPE
HAS_BODY


class Net::HTTPServerException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPServerException

In Files

  • lib/net/http/exceptions.rb

Parent

Net::ProtoServerError

Included Modules

  • Net::HTTPExceptions


class Net::HTTPServiceUnavailable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPServiceUnavailable

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPServerError

Constants

HAS_BODY


class Net::HTTPSuccess - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPSuccess

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPResponse

Constants

EXCEPTION_TYPE
HAS_BODY


class Net::HTTPSwitchProtocol - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPSwitchProtocol

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPInformation

Constants

HAS_BODY


class Net::HTTPTemporaryRedirect - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPTemporaryRedirect

306 Switch Proxy - no longer unused

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPRedirection

Constants

HAS_BODY


class Net::HTTPTooManyRequests - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPTooManyRequests

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPUnauthorized - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPUnauthorized

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPUnknownResponse - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPUnknownResponse

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPResponse

Constants

EXCEPTION_TYPE
HAS_BODY


class Net::HTTPUnprocessableEntity - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPUnprocessableEntity

418 I'm a teapot - RFC 2324; a joke RFC 420 Enhance Your Calm - Twitter

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPUnsupportedMediaType - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPUnsupportedMediaType

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPUpgradeRequired - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPUpgradeRequired

425 Unordered Collection - existed only in draft

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPClientError

Constants

HAS_BODY


class Net::HTTPUseProxy - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPUseProxy

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPRedirection

Constants

HAS_BODY


class Net::HTTPVersionNotSupported - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::HTTPVersionNotSupported

In Files

  • lib/net/http/responses.rb

Parent

Net::HTTPServerError

Constants

HAS_BODY


class Net::IMAP - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP

Net::IMAP implements Internet Message Access Protocol (IMAP) client functionality. The protocol is described in [IMAP].

IMAP Overview

An IMAP client connects to a server, and then authenticates itself using either authenticate() or login(). Having authenticated itself, there is a range of commands available to it. Most work with mailboxes, which may be arranged in an hierarchical namespace, and each of which contains zero or more messages. How this is implemented on the server is implementation-dependent; on a UNIX server, it will frequently be implemented as a files in mailbox format within a hierarchy of directories.

To work on the messages within a mailbox, the client must first select that mailbox, using either select() or (for read-only access) examine(). Once the client has successfully selected a mailbox, they enter selected state, and that mailbox becomes the current mailbox, on which mail-item related commands implicitly operate.

Messages have two sorts of identifiers: message sequence numbers, and UIDs.

Message sequence numbers number messages within a mail box from 1 up to the number of items in the mail box. If new message arrives during a session, it receives a sequence number equal to the new size of the mail box. If messages are expunged from the mailbox, remaining messages have their sequence numbers “shuffled down” to fill the gaps.

UIDs, on the other hand, are permanently guaranteed not to identify another message within the same mailbox, even if the existing message is deleted. UIDs are required to be assigned in ascending (but not necessarily sequential) order within a mailbox; this means that if a non-IMAP client rearranges the order of mailitems within a mailbox, the UIDs have to be reassigned. An IMAP client cannot thus rearrange message orders.

Examples of Usage

List sender and subject of all recent messages in the default mailbox

imap = Net::IMAP.new('mail.example.com')
imap.authenticate('LOGIN', 'joe_user', 'joes_password')
imap.examine('INBOX')
imap.search(["RECENT"]).each do |message_id|
  envelope = imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"]
  puts "#{envelope.from[0].name}: \t#{envelope.subject}"
end

Move all messages from April 2003 from “Mail/sent-mail” to “Mail/sent-apr03”

imap = Net::IMAP.new('mail.example.com')
imap.authenticate('LOGIN', 'joe_user', 'joes_password')
imap.select('Mail/sent-mail')
if not imap.list('Mail/', 'sent-apr03')
  imap.create('Mail/sent-apr03')
end
imap.search(["BEFORE", "30-Apr-2003", "SINCE", "1-Apr-2003"]).each do |message_id|
  imap.copy(message_id, "Mail/sent-apr03")
  imap.store(message_id, "+FLAGS", [:Deleted])
end
imap.expunge

Thread Safety

Net::IMAP supports concurrent threads. For example,

imap = Net::IMAP.new("imap.foo.net", "imap2")
imap.authenticate("cram-md5", "bar", "password")
imap.select("inbox")
fetch_thread = Thread.start { imap.fetch(1..-1, "UID") }
search_result = imap.search(["BODY", "hello"])
fetch_result = fetch_thread.value
imap.disconnect

This script invokes the FETCH command and the SEARCH command concurrently.

Errors

An IMAP server can send three different types of responses to indicate failure:

NO

the attempted command could not be successfully completed. For instance, the username/password used for logging in are incorrect; the selected mailbox does not exists; etc.

BAD

the request from the client does not follow the server's understanding of the IMAP protocol. This includes attempting commands from the wrong client state; for instance, attempting to perform a SEARCH command without having SELECTed a current mailbox. It can also signal an internal server failure (such as a disk crash) has occurred.

BYE

the server is saying goodbye. This can be part of a normal logout sequence, and can be used as part of a login sequence to indicate that the server is (for some reason) unwilling to accept our connection. As a response to any other command, it indicates either that the server is shutting down, or that the server is timing out the client connection due to inactivity.

These three error response are represented by the errors Net::IMAP::NoResponseError, Net::IMAP::BadResponseError, and Net::IMAP::ByeResponseError, all of which are subclasses of Net::IMAP::ResponseError. Essentially, all methods that involve sending a request to the server can generate one of these errors. Only the most pertinent instances have been documented below.

Because the IMAP class uses Sockets for communication, its methods are also susceptible to the various errors that can occur when working with sockets. These are generally represented as Errno errors. For instance, any method that involves sending a request to the server and/or receiving a response from it could raise an Errno::EPIPE error if the network connection unexpectedly goes down. See the socket(7), ip(7), tcp(7), socket(2), connect(2), and associated man pages.

Finally, a Net::IMAP::DataFormatError is thrown if low-level data is found to be in an incorrect format (for instance, when converting between UTF-8 and UTF-16), and Net::IMAP::ResponseParseError is thrown if a server response is non-parseable.

References

[IMAP]

  1. Crispin, “INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1”,

RFC 2060, December 1996. (Note: since obsoleted by RFC 3501)

[LANGUAGE-TAGS]

Alvestrand, H., “Tags for the Identification of Languages”, RFC 1766, March 1995.

[MD5]

Myers, J., and M. Rose, “The Content-MD5 Header Field”, RFC 1864, October 1995.

[MIME-IMB]

Freed, N., and N. Borenstein, “MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies”, RFC 2045, November 1996.

[RFC-822]

Crocker, D., “Standard for the Format of ARPA Internet Text Messages”, STD 11, RFC 822, University of Delaware, August 1982.

[RFC-2087]

Myers, J., “IMAP4 QUOTA extension”, RFC 2087, January 1997.

[RFC-2086]

Myers, J., “IMAP4 ACL extension”, RFC 2086, January 1997.

[RFC-2195]

Klensin, J., Catoe, R., and Krumviede, P., “IMAP/POP AUTHorize Extension for Simple Challenge/Response”, RFC 2195, September 1997.

[SORT-THREAD-EXT]

Crispin, M., “INTERNET MESSAGE ACCESS PROTOCOL - SORT and THREAD Extensions”, draft-ietf-imapext-sort, May 2003.

[OSSL]

www.openssl.org

[RSSL]

savannah.gnu.org/projects/rubypki

[UTF7]

Goldsmith, D. and Davis, M., “UTF-7: A Mail-Safe Transformation Format of Unicode”, RFC 2152, May 1997.

In Files

  • lib/net/imap.rb

Parent

Object

Included Modules

  • MonitorMixin
  • OpenSSL
  • OpenSSL::SSL

Constants

ANSWERED

Flag indicating a message has been answered

Address

Net::IMAP::Address represents electronic mail addresses.

Fields:

name

Returns the phrase from [RFC-822] mailbox.

route

Returns the route from [RFC-822] route-addr.

mailbox

nil indicates end of [RFC-822] group. If non-nil and host is nil, returns [RFC-822] group name. Otherwise, returns [RFC-822] local-part

host

nil indicates [RFC-822] group syntax. Otherwise, returns [RFC-822] domain name.

ContentDisposition

Net::IMAP::ContentDisposition represents Content-Disposition fields.

Fields:

dsp_type

Returns the disposition type.

param

Returns a hash that represents parameters of the Content-Disposition field.

ContinuationRequest

Net::IMAP::ContinuationRequest represents command continuation requests.

The command continuation request response is indicated by a “+” token instead of a tag. This form of response indicates that the server is ready to accept the continuation of a command from the client. The remainder of this response is a line of text.

continue_req    ::= "+" SPACE (resp_text / base64)

Fields:

data

Returns the data (Net::IMAP::ResponseText).

raw_data

Returns the raw data string.

DATE_MONTH
DELETED

Flag indicating a message has been marked for deletion. This will occur when the mailbox is closed or expunged.

DRAFT

Flag indicating a message is only a draft or work-in-progress version.

Envelope

Net::IMAP::Envelope represents envelope structures of messages.

Fields:

date

Returns a string that represents the date.

subject

Returns a string that represents the subject.

from

Returns an array of Net::IMAP::Address that represents the from.

sender

Returns an array of Net::IMAP::Address that represents the sender.

reply_to

Returns an array of Net::IMAP::Address that represents the reply-to.

to

Returns an array of Net::IMAP::Address that represents the to.

cc

Returns an array of Net::IMAP::Address that represents the cc.

bcc

Returns an array of Net::IMAP::Address that represents the bcc.

in_reply_to

Returns a string that represents the in-reply-to.

message_id

Returns a string that represents the message-id.

FLAGGED

Flag indicating a message has been flagged for special or urgent attention

FetchData

Net::IMAP::FetchData represents contents of the FETCH response.

Fields:

seqno

Returns the message sequence number. (Note: not the unique identifier, even for the UID command response.)

attr

Returns a hash. Each key is a data item name, and each value is its value.

The current data items are:

BODY

A form of BODYSTRUCTURE without extension data.

Net::IMAP::BodyTypeBasic, Net::IMAP::BodyTypeText, Net::IMAP::BodyTypeMessage, Net::IMAP::BodyTypeMultipart.

ENVELOPE

A Net::IMAP::Envelope object that describes the envelope structure of a message.

FLAGS

A array of flag symbols that are set for this message. flag symbols are capitalized by String#capitalize.

INTERNALDATE

A string representing the internal date of the message.

RFC822

Equivalent to BODY[].

RFC822.HEADER

Equivalent to BODY.PEEK.

RFC822.SIZE

A number expressing the [RFC-822] size of the message.

RFC822.TEXT

Equivalent to BODY.

UID

A number expressing the unique identifier of the message.

MARKED

Flag indicating that a mailbox has been marked “interesting” by the server; this commonly indicates that the mailbox contains new messages.

MailboxACLItem

Net::IMAP::MailboxACLItem represents response from GETACL.

acl_data        ::= "ACL" SPACE mailbox *(SPACE identifier SPACE rights)

identifier      ::= astring

rights          ::= astring

Fields:

user

Login name that has certain rights to the mailbox that was specified with the getacl command.

rights

The access rights the indicated user has to the mailbox.

MailboxList

Net::IMAP::MailboxList represents contents of the LIST response.

mailbox_list    ::= "(" #("\Marked" / "\Noinferiors" /
                    "\Noselect" / "\Unmarked" / flag_extension) ")"
                    SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox

Fields:

attr

Returns the name attributes. Each name attribute is a symbol capitalized by String#capitalize, such as :Noselect (not :NoSelect).

delim

Returns the hierarchy delimiter

name

Returns the mailbox name.

MailboxQuota

Net::IMAP::MailboxQuota represents contents of GETQUOTA response. This object can also be a response to GETQUOTAROOT. In the syntax specification below, the delimiter used with the “#” construct is a single space (SPACE).

quota_list      ::= "(" #quota_resource ")"

quota_resource  ::= atom SPACE number SPACE number

quota_response  ::= "QUOTA" SPACE astring SPACE quota_list

Fields:

mailbox

The mailbox with the associated quota.

usage

Current storage usage of mailbox.

quota

Quota limit imposed on mailbox.

MailboxQuotaRoot

Net::IMAP::MailboxQuotaRoot represents part of the GETQUOTAROOT response. (GETQUOTAROOT can also return Net::IMAP::MailboxQuota.)

quotaroot_response ::= "QUOTAROOT" SPACE astring *(SPACE astring)

Fields:

mailbox

The mailbox with the associated quota.

quotaroots

Zero or more quotaroots that effect the quota on the specified mailbox.

NOINFERIORS

Flag indicating that a mailbox context name cannot contain children.

NOSELECT

Flag indicating that a mailbox is not selected.

RECENT

Flag indicating that the message is “recent”, meaning that this session is the first session in which the client has been notified of this message.

ResponseCode

Net::IMAP::ResponseCode represents response codes.

resp_text_code  ::= "ALERT" / "PARSE" /
                    "PERMANENTFLAGS" SPACE "(" #(flag / "\*") ")" /
                    "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
                    "UIDVALIDITY" SPACE nz_number /
                    "UNSEEN" SPACE nz_number /
                    atom [SPACE 1*<any TEXT_CHAR except "]">]

Fields:

name

Returns the name such as “ALERT”, “PERMANENTFLAGS”, “UIDVALIDITY”.…

data

Returns the data if it exists.

ResponseText

Net::IMAP::ResponseText represents texts of responses. The text may be prefixed by the response code.

resp_text       ::= ["[" resp_text_code "]" SPACE] (text_mime2 / text)
                    ;; text SHOULD NOT begin with "[" or "="

Fields:

code

Returns the response code. See ((<Net::IMAP::ResponseCode>)).

text

Returns the text.

SEEN

Flag indicating a message has been seen

StatusData

Net::IMAP::StatusData represents contents of the STATUS response.

Fields:

mailbox

Returns the mailbox name.

attr

Returns a hash. Each key is one of “MESSAGES”, “RECENT”, “UIDNEXT”, “UIDVALIDITY”, “UNSEEN”. Each value is a number.

TaggedResponse

Net::IMAP::TaggedResponse represents tagged responses.

The server completion result response indicates the success or failure of the operation. It is tagged with the same tag as the client command which began the operation.

response_tagged ::= tag SPACE resp_cond_state CRLF

tag             ::= 1*<any ATOM_CHAR except "+">

resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text

Fields:

tag

Returns the tag.

name

Returns the name. the name is one of “OK”, “NO”, “BAD”.

data

Returns the data. See ((<Net::IMAP::ResponseText>)).

raw_data

Returns the raw data string.

ThreadMember

Net::IMAP::ThreadMember represents a thread-node returned by #thread

Fields:

seqno

The sequence number of this message.

children

an array of Net::IMAP::ThreadMember objects for mail

items that are children of this in the thread.

UNMARKED

Flag indicating that the mailbox does not contains new messages.

UntaggedResponse

Net::IMAP::UntaggedResponse represents untagged responses.

Data transmitted by the server to the client and status responses that do not indicate command completion are prefixed with the token “*”, and are called untagged responses.

response_data   ::= "*" SPACE (resp_cond_state / resp_cond_bye /
                    mailbox_data / message_data / capability_data)

Fields:

name

Returns the name such as “FLAGS”, “LIST”, “FETCH”.…

data

Returns the data such as an array of flag symbols,

a ((<Net::IMAP::MailboxList>)) object....
raw_data

Returns the raw data string.

Attributes

client_thread[RW]

The thread to receive exceptions.

greeting[R]

Returns an initial greeting response from the server.

response_handlers[R]

Returns all response handlers.

responses[R]

Returns recorded untagged responses. For example:

imap.select("inbox")
p imap.responses["EXISTS"][-1]
#=> 2
p imap.responses["UIDVALIDITY"][-1]
#=> 968263756

Public Class Methods

add_authenticator(auth_type, authenticator) click to toggle source

Adds an authenticator for #authenticate. auth_type is the type of authentication this authenticator supports (for instance, “LOGIN”). The authenticator is an object which defines a process() method to handle authentication with the server. See Net::IMAP::LoginAuthenticator, Net::IMAP::CramMD5Authenticator, and Net::IMAP::DigestMD5Authenticator for examples.

If auth_type refers to an existing authenticator, it will be replaced by the new one.

# File lib/net/imap.rb, line 294
def self.add_authenticator(auth_type, authenticator)
  @@authenticators[auth_type] = authenticator
end
debug() click to toggle source

Returns the debug mode.

# File lib/net/imap.rb, line 264
def self.debug
  return @@debug
end
debug=(val) click to toggle source

Sets the debug mode.

# File lib/net/imap.rb, line 269
def self.debug=(val)
  return @@debug = val
end
decode_utf7(s) click to toggle source

Decode a string from modified UTF-7 format to UTF-8.

UTF-7 is a 7-bit encoding of Unicode [UTF7]. IMAP uses a slightly modified version of this to encode mailbox names containing non-ASCII characters; see [IMAP] section 5.1.3.

Net::IMAP does not automatically encode and decode mailbox names to and from utf7.

# File lib/net/imap.rb, line 957
def self.decode_utf7(s)
  return s.gsub(/&([^-]+)?-/) {
    if $1
      ($1.tr(",", "/") + "===").unpack("m")[0].encode(Encoding::UTF_8, Encoding::UTF_16BE)
    else
      "&"
    end
  }
end
default_imap_port() click to toggle source
Alias for: default_port
default_imaps_port() click to toggle source
Alias for: default_tls_port
default_port() click to toggle source

The default port for IMAP connections, port 143

# File lib/net/imap.rb, line 299
def self.default_port
  return PORT
end
Also aliased as: default_imap_port
default_ssl_port() click to toggle source
Alias for: default_tls_port
default_tls_port() click to toggle source

The default port for IMAPS connections, port 993

# File lib/net/imap.rb, line 304
def self.default_tls_port
  return SSL_PORT
end
Also aliased as: default_imaps_port, default_ssl_port
encode_utf7(s) click to toggle source

Encode a string from UTF-8 format to modified UTF-7.

# File lib/net/imap.rb, line 968
def self.encode_utf7(s)
  return s.gsub(/(&)|[^\x20-\x7e]+/) {
    if $1
      "&-"
    else
      base64 = [$&.encode(Encoding::UTF_16BE)].pack("m")
      "&" + base64.delete("=\n").tr("/", ",") + "-"
    end
  }.force_encoding("ASCII-8BIT")
end
format_date(time) click to toggle source

Formats time as an IMAP-style date.

# File lib/net/imap.rb, line 980
def self.format_date(time)
  return time.strftime('%d-%b-%Y')
end
format_datetime(time) click to toggle source

Formats time as an IMAP-style date-time.

# File lib/net/imap.rb, line 985
def self.format_datetime(time)
  return time.strftime('%d-%b-%Y %H:%M %z')
end
max_flag_count() click to toggle source

Returns the max number of flags interned to symbols.

# File lib/net/imap.rb, line 274
def self.max_flag_count
  return @@max_flag_count
end
max_flag_count=(count) click to toggle source

Sets the max number of flags interned to symbols.

# File lib/net/imap.rb, line 279
def self.max_flag_count=(count)
  @@max_flag_count = count
end
Net::IMAP.new(host, options = {}) click to toggle source

Creates a new Net::IMAP object and connects it to the specified host.

options is an option hash, each key of which is a symbol.

The available options are:

port

port number (default value is 143 for imap, or 993 for imaps)

ssl

if options is true, then an attempt will be made to use SSL (now TLS) to connect to the server. For this to work OpenSSL [OSSL] and the Ruby OpenSSL [RSSL] extensions need to be installed. if options is a hash, it's passed to OpenSSL::SSL::SSLContext#set_params as parameters.

The most common errors are:

Errno::ECONNREFUSED

connection refused by host or an intervening firewall.

Errno::ETIMEDOUT

connection timed out (possibly due to packets being dropped by an intervening firewall).

Errno::ENETUNREACH

there is no route to that network.

SocketError

hostname not known or other socket error.

Net::IMAP::ByeResponseError

we connected to the host, but they immediately said goodbye to us.

# File lib/net/imap.rb, line 1027
def initialize(host, port_or_options = {},
               usessl = false, certs = nil, verify = true)
  super()
  @host = host
  begin
    options = port_or_options.to_hash
  rescue NoMethodError
    # for backward compatibility
    options = {}
    options[:port] = port_or_options
    if usessl
      options[:ssl] = create_ssl_params(certs, verify)
    end
  end
  @port = options[:port] || (options[:ssl] ? SSL_PORT : PORT)
  @tag_prefix = "RUBY"
  @tagno = 0
  @parser = ResponseParser.new
  @sock = TCPSocket.open(@host, @port)
  if options[:ssl]
    start_tls_session(options[:ssl])
    @usessl = true
  else
    @usessl = false
  end
  @responses = Hash.new([].freeze)
  @tagged_responses = {}
  @response_handlers = []
  @tagged_response_arrival = new_cond
  @continuation_request_arrival = new_cond
  @idle_done_cond = nil
  @logout_command_tag = nil
  @debug_output_bol = true
  @exception = nil

  @greeting = get_response
  if @greeting.nil?
    @sock.close
    raise Error, "connection closed"
  end
  if @greeting.name == "BYE"
    @sock.close
    raise ByeResponseError, @greeting
  end

  @client_thread = Thread.current
  @receiver_thread = Thread.start {
    begin
      receive_responses
    rescue Exception
    end
  }
  @receiver_thread_terminating = false
end

Public Instance Methods

add_response_handler(handler = Proc.new) click to toggle source

Adds a response handler. For example, to detect when the server sends us a new EXISTS response (which normally indicates new messages being added to the mail box), you could add the following handler after selecting the mailbox.

imap.add_response_handler { |resp|
  if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS"
    puts "Mailbox now has #{resp.data} messages"
  end
}

# File lib/net/imap.rb, line 874
def add_response_handler(handler = Proc.new)
  @response_handlers.push(handler)
end
append(mailbox, message, flags = nil, date_time = nil) click to toggle source

Sends a APPEND command to append the message to the end of the mailbox. The optional flags argument is an array of flags to initially passing to the new message. The optional date_time argument specifies the creation time to assign to the new message; it defaults to the current time. For example:

imap.append("inbox", <<EOF.gsub(/\n/, "\r\n"), [:Seen], Time.now)
Subject: hello
From: shugo@ruby-lang.org
To: shugo@ruby-lang.org

hello world
EOF

A Net::IMAP::NoResponseError is raised if the mailbox does not exist (it is not created automatically), or if the flags, date_time, or message arguments contain errors.

# File lib/net/imap.rb, line 693
def append(mailbox, message, flags = nil, date_time = nil)
  args = []
  if flags
    args.push(flags)
  end
  args.push(date_time) if date_time
  args.push(Literal.new(message))
  send_command("APPEND", mailbox, *args)
end
authenticate(auth_type, *args) click to toggle source

Sends an AUTHENTICATE command to authenticate the client. The auth_type parameter is a string that represents the authentication mechanism to be used. Currently Net::IMAP supports authentication mechanisms:

LOGIN:: login using cleartext user and password.
CRAM-MD5:: login with cleartext user and encrypted password
           (see [RFC-2195] for a full description).  This
           mechanism requires that the server have the user's
           password stored in clear-text password.

For both these mechanisms, there should be two args: username and (cleartext) password. A server may not support one or other of these mechanisms; check capability() for a capability of the form “AUTH=LOGIN” or “AUTH=CRAM-MD5”.

Authentication is done using the appropriate authenticator object: see @@authenticators for more information on plugging in your own authenticator.

For example:

imap.authenticate('LOGIN', user, password)

A Net::IMAP::NoResponseError is raised if authentication fails.

# File lib/net/imap.rb, line 411
def authenticate(auth_type, *args)
  auth_type = auth_type.upcase
  unless @@authenticators.has_key?(auth_type)
    raise ArgumentError,
      format('unknown auth type - "%s"', auth_type)
  end
  authenticator = @@authenticators[auth_type].new(*args)
  send_command("AUTHENTICATE", auth_type) do |resp|
    if resp.instance_of?(ContinuationRequest)
      data = authenticator.process(resp.data.text.unpack("m")[0])
      s = [data].pack("m").gsub(/\n/, "")
      send_string_data(s)
      put_string(CRLF)
    end
  end
end
capability() click to toggle source

Sends a CAPABILITY command, and returns an array of capabilities that the server supports. Each capability is a string. See [IMAP] for a list of possible capabilities.

Note that the Net::IMAP class does not modify its behaviour according to the capabilities of the server; it is up to the user of the class to ensure that a certain capability is supported by a server before using it.

# File lib/net/imap.rb, line 353
def capability
  synchronize do
    send_command("CAPABILITY")
    return @responses.delete("CAPABILITY")[-1]
  end
end
check() click to toggle source

Sends a CHECK command to request a checkpoint of the currently selected mailbox. This performs implementation-specific housekeeping, for instance, reconciling the mailbox's in-memory and on-disk state.

# File lib/net/imap.rb, line 707
def check
  send_command("CHECK")
end
close() click to toggle source

Sends a CLOSE command to close the currently selected mailbox. The CLOSE command permanently removes from the mailbox all messages that have the Deleted flag set.

# File lib/net/imap.rb, line 714
def close
  send_command("CLOSE")
end
copy(set, mailbox) click to toggle source

Sends a COPY command to copy the specified message(s) to the end of the specified destination mailbox. The set parameter is a number or an array of numbers or a Range object. The number is a message sequence number.

# File lib/net/imap.rb, line 835
def copy(set, mailbox)
  copy_internal("COPY", set, mailbox)
end
create(mailbox) click to toggle source

Sends a CREATE command to create a new mailbox.

A Net::IMAP::NoResponseError is raised if a mailbox with that name cannot be created.

# File lib/net/imap.rb, line 474
def create(mailbox)
  send_command("CREATE", mailbox)
end
delete(mailbox) click to toggle source

Sends a DELETE command to remove the mailbox.

A Net::IMAP::NoResponseError is raised if a mailbox with that name cannot be deleted, either because it does not exist or because the client does not have permission to delete it.

# File lib/net/imap.rb, line 483
def delete(mailbox)
  send_command("DELETE", mailbox)
end
disconnect() click to toggle source

Disconnects from the server.

# File lib/net/imap.rb, line 315
def disconnect
  begin
    begin
      # try to call SSL::SSLSocket#io.
      @sock.io.shutdown
    rescue NoMethodError
      # @sock is not an SSL::SSLSocket.
      @sock.shutdown
    end
  rescue Errno::ENOTCONN
    # ignore `Errno::ENOTCONN: Socket is not connected' on some platforms.
  rescue Exception => e
    @receiver_thread.raise(e)
  end
  @receiver_thread.join
  synchronize do
    unless @sock.closed?
      @sock.close
    end
  end
  raise e if e
end
disconnected?() click to toggle source

Returns true if disconnected from the server.

# File lib/net/imap.rb, line 339
def disconnected?
  return @sock.closed?
end
examine(mailbox) click to toggle source

Sends a EXAMINE command to select a mailbox so that messages in the mailbox can be accessed. Behaves the same as select(), except that the selected mailbox is identified as read-only.

A Net::IMAP::NoResponseError is raised if the mailbox does not exist or is for some reason non-examinable.

# File lib/net/imap.rb, line 463
def examine(mailbox)
  synchronize do
    @responses.clear
    send_command("EXAMINE", mailbox)
  end
end
expunge() click to toggle source

Sends a EXPUNGE command to permanently remove from the currently selected mailbox all messages that have the Deleted flag set.

# File lib/net/imap.rb, line 720
def expunge
  synchronize do
    send_command("EXPUNGE")
    return @responses.delete("EXPUNGE")
  end
end
fetch(set, attr) click to toggle source

Sends a FETCH command to retrieve data associated with a message in the mailbox. The set parameter is a number or an array of numbers or a Range object. The number is a message sequence number. attr is a list of attributes to fetch; see the documentation for Net::IMAP::FetchData for a list of valid attributes. The return value is an array of Net::IMAP::FetchData. For example:

p imap.fetch(6..8, "UID")
#=> [#<Net::IMAP::FetchData seqno=6, attr={"UID"=>98}>, \\
     #<Net::IMAP::FetchData seqno=7, attr={"UID"=>99}>, \\
     #<Net::IMAP::FetchData seqno=8, attr={"UID"=>100}>]
p imap.fetch(6, "BODY[HEADER.FIELDS (SUBJECT)]")
#=> [#<Net::IMAP::FetchData seqno=6, attr={"BODY[HEADER.FIELDS (SUBJECT)]"=>"Subject: test\r\n\r\n"}>]
data = imap.uid_fetch(98, ["RFC822.SIZE", "INTERNALDATE"])[0]
p data.seqno
#=> 6
p data.attr["RFC822.SIZE"]
#=> 611
p data.attr["INTERNALDATE"]
#=> "12-Oct-2000 22:40:59 +0900"
p data.attr["UID"]
#=> 98

# File lib/net/imap.rb, line 799
def fetch(set, attr)
  return fetch_internal("FETCH", set, attr)
end
getacl(mailbox) click to toggle source

Send the GETACL command along with specified mailbox. If this mailbox exists, an array containing objects of Net::IMAP::MailboxACLItem will be returned.

# File lib/net/imap.rb, line 633
def getacl(mailbox)
  synchronize do
    send_command("GETACL", mailbox)
    return @responses.delete("ACL")[-1]
  end
end
getquota(mailbox) click to toggle source

Sends the GETQUOTA command along with specified mailbox. If this mailbox exists, then an array containing a Net::IMAP::MailboxQuota object is returned. This command generally is only available to server admin.

# File lib/net/imap.rb, line 597
def getquota(mailbox)
  synchronize do
    send_command("GETQUOTA", mailbox)
    return @responses.delete("QUOTA")
  end
end
getquotaroot(mailbox) click to toggle source

Sends the GETQUOTAROOT command along with specified mailbox. This command is generally available to both admin and user. If mailbox exists, returns an array containing objects of Net::IMAP::MailboxQuotaRoot and Net::IMAP::MailboxQuota.

# File lib/net/imap.rb, line 583
def getquotaroot(mailbox)
  synchronize do
    send_command("GETQUOTAROOT", mailbox)
    result = []
    result.concat(@responses.delete("QUOTAROOT"))
    result.concat(@responses.delete("QUOTA"))
    return result
  end
end
idle(&response_handler) click to toggle source

Sends an IDLE command that waits for notifications of new or expunged messages. Yields responses from the server during the IDLE.

Use idle_done() to leave IDLE.

# File lib/net/imap.rb, line 910
def idle(&response_handler)
  raise LocalJumpError, "no block given" unless response_handler

  response = nil

  synchronize do
    tag = Thread.current[:net_imap_tag] = generate_tag
    put_string("#{tag} IDLE#{CRLF}")

    begin
      add_response_handler(response_handler)
      @idle_done_cond = new_cond
      @idle_done_cond.wait
      @idle_done_cond = nil
      if @receiver_thread_terminating
        raise Net::IMAP::Error, "connection closed"
      end
    ensure
      unless @receiver_thread_terminating
        remove_response_handler(response_handler)
        put_string("DONE#{CRLF}")
        response = get_tagged_response(tag, "IDLE")
      end
    end
  end

  return response
end
idle_done() click to toggle source

Leaves IDLE.

# File lib/net/imap.rb, line 940
def idle_done
  synchronize do
    if @idle_done_cond.nil?
      raise Net::IMAP::Error, "not during IDLE"
    end
    @idle_done_cond.signal
  end
end
list(refname, mailbox) click to toggle source

Sends a LIST command, and returns a subset of names from the complete set of all names available to the client. refname provides a context (for instance, a base directory in a directory-based mailbox hierarchy). mailbox specifies a mailbox or (via wildcards) mailboxes under that context. Two wildcards may be used in mailbox: '*', which matches all characters including the hierarchy delimiter (for instance, '/' on a UNIX-hosted directory-based mailbox hierarchy); and '%', which matches all characters except the hierarchy delimiter.

If refname is empty, mailbox is used directly to determine which mailboxes to match. If mailbox is empty, the root name of refname and the hierarchy delimiter are returned.

The return value is an array of +Net::IMAP::MailboxList+. For example:

imap.create("foo/bar")
imap.create("foo/baz")
p imap.list("", "foo/%")
#=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim="/", name="foo/">, \\
     #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim="/", name="foo/bar">, \\
     #<Net::IMAP::MailboxList attr=[:Noinferiors], delim="/", name="foo/baz">]

# File lib/net/imap.rb, line 540
def list(refname, mailbox)
  synchronize do
    send_command("LIST", refname, mailbox)
    return @responses.delete("LIST")
  end
end
login(user, password) click to toggle source

Sends a LOGIN command to identify the client and carries the plaintext password authenticating this user. Note that, unlike calling authenticate() with an auth_type of “LOGIN”, login() does not use the login authenticator.

A Net::IMAP::NoResponseError is raised if authentication fails.

# File lib/net/imap.rb, line 434
def login(user, password)
  send_command("LOGIN", user, password)
end
logout() click to toggle source

Sends a LOGOUT command to inform the server that the client is done with the connection.

# File lib/net/imap.rb, line 367
def logout
  send_command("LOGOUT")
end
lsub(refname, mailbox) click to toggle source

Sends a LSUB command, and returns a subset of names from the set of names that the user has declared as being “active” or “subscribed”. refname and mailbox are interpreted as for list(). The return value is an array of +Net::IMAP::MailboxList+.

# File lib/net/imap.rb, line 645
def lsub(refname, mailbox)
  synchronize do
    send_command("LSUB", refname, mailbox)
    return @responses.delete("LSUB")
  end
end
noop() click to toggle source

Sends a NOOP command to the server. It does nothing.

# File lib/net/imap.rb, line 361
def noop
  send_command("NOOP")
end
remove_response_handler(handler) click to toggle source

Removes the response handler.

# File lib/net/imap.rb, line 879
def remove_response_handler(handler)
  @response_handlers.delete(handler)
end
rename(mailbox, newname) click to toggle source

Sends a RENAME command to change the name of the mailbox to newname.

A Net::IMAP::NoResponseError is raised if a mailbox with the name mailbox cannot be renamed to newname for whatever reason; for instance, because mailbox does not exist, or because there is already a mailbox with the name newname.

# File lib/net/imap.rb, line 494
def rename(mailbox, newname)
  send_command("RENAME", mailbox, newname)
end
search(keys, charset = nil) click to toggle source

Sends a SEARCH command to search the mailbox for messages that match the given searching criteria, and returns message sequence numbers. keys can either be a string holding the entire search string, or a single-dimension array of search keywords and arguments. The following are some common search criteria; see [IMAP] section 6.4.4 for a full list.

<message set>

a set of message sequence numbers. ',' indicates an interval, ':' indicates a range. For instance, '2,10:12,15' means “2,10,11,12,15”.

BEFORE <date>

messages with an internal date strictly before <date>. The date argument has a format similar to 8-Aug-2002.

BODY <string>

messages that contain <string> within their body.

CC <string>

messages containing <string> in their CC field.

FROM <string>

messages that contain <string> in their FROM field.

NEW

messages with the Recent, but not the Seen, flag set.

NOT <search-key>

negate the following search key.

OR <search-key> <search-key>

“or” two search keys together.

ON <date>

messages with an internal date exactly equal to <date>, which has a format similar to 8-Aug-2002.

SINCE <date>

messages with an internal date on or after <date>.

SUBJECT <string>

messages with <string> in their subject.

TO <string>

messages with <string> in their TO field.

For example:

p imap.search(["SUBJECT", "hello", "NOT", "NEW"])
#=> [1, 6, 7, 8]

# File lib/net/imap.rb, line 767
def search(keys, charset = nil)
  return search_internal("SEARCH", keys, charset)
end
select(mailbox) click to toggle source

Sends a SELECT command to select a mailbox so that messages in the mailbox can be accessed.

After you have selected a mailbox, you may retrieve the number of items in that mailbox from @responses[-1], and the number of recent messages from @responses[-1]. Note that these values can change if new messages arrive during a session; see add_response_handler() for a way of detecting this event.

A Net::IMAP::NoResponseError is raised if the mailbox does not exist or is for some reason non-selectable.

# File lib/net/imap.rb, line 450
def select(mailbox)
  synchronize do
    @responses.clear
    send_command("SELECT", mailbox)
  end
end
setacl(mailbox, user, rights) click to toggle source

Sends the SETACL command along with mailbox, user and the rights that user is to have on that mailbox. If rights is nil, then that user will be stripped of any rights to that mailbox. The IMAP ACL commands are described in [RFC-2086].

# File lib/net/imap.rb, line 622
def setacl(mailbox, user, rights)
  if rights.nil?
    send_command("SETACL", mailbox, user, "")
  else
    send_command("SETACL", mailbox, user, rights)
  end
end
setquota(mailbox, quota) click to toggle source

Sends a SETQUOTA command along with the specified mailbox and quota. If quota is nil, then quota will be unset for that mailbox. Typically one needs to be logged in as server admin for this to work. The IMAP quota commands are described in [RFC-2087].

# File lib/net/imap.rb, line 609
def setquota(mailbox, quota)
  if quota.nil?
    data = '()'
  else
    data = '(STORAGE ' + quota.to_s + ')'
  end
  send_command("SETQUOTA", mailbox, RawData.new(data))
end
sort(sort_keys, search_keys, charset) click to toggle source

Sends a SORT command to sort messages in the mailbox. Returns an array of message sequence numbers. For example:

p imap.sort(["FROM"], ["ALL"], "US-ASCII")
#=> [1, 2, 3, 5, 6, 7, 8, 4, 9]
p imap.sort(["DATE"], ["SUBJECT", "hello"], "US-ASCII")
#=> [6, 7, 8, 1]

See [SORT-THREAD-EXT] for more details.

# File lib/net/imap.rb, line 853
def sort(sort_keys, search_keys, charset)
  return sort_internal("SORT", sort_keys, search_keys, charset)
end
starttls(options = {}, verify = true) click to toggle source

Sends a STARTTLS command to start TLS session.

# File lib/net/imap.rb, line 372
def starttls(options = {}, verify = true)
  send_command("STARTTLS") do |resp|
    if resp.kind_of?(TaggedResponse) && resp.name == "OK"
      begin
        # for backward compatibility
        certs = options.to_str
        options = create_ssl_params(certs, verify)
      rescue NoMethodError
      end
      start_tls_session(options)
    end
  end
end
status(mailbox, attr) click to toggle source

Sends a STATUS command, and returns the status of the indicated mailbox. attr is a list of one or more attributes that we are request the status of. Supported attributes include:

MESSAGES:: the number of messages in the mailbox.
RECENT:: the number of recent messages in the mailbox.
UNSEEN:: the number of unseen messages in the mailbox.

The return value is a hash of attributes. For example:

p imap.status("inbox", ["MESSAGES", "RECENT"])
#=> {"RECENT"=>0, "MESSAGES"=>44}

A Net::IMAP::NoResponseError is raised if status values for mailbox cannot be returned, for instance because it does not exist.

# File lib/net/imap.rb, line 668
def status(mailbox, attr)
  synchronize do
    send_command("STATUS", mailbox, attr)
    return @responses.delete("STATUS")[-1].attr
  end
end
store(set, attr, flags) click to toggle source

Sends a STORE command to alter data associated with messages in the mailbox, in particular their flags. The set parameter is a number or an array of numbers or a Range object. Each number is a message sequence number. attr is the name of a data item to store: 'FLAGS' means to replace the message's flag list with the provided one; '+FLAGS' means to add the provided flags; and '-FLAGS' means to remove them. flags is a list of flags.

The return value is an array of Net::IMAP::FetchData. For example:

p imap.store(6..8, "+FLAGS", [:Deleted])
#=> [#<Net::IMAP::FetchData seqno=6, attr={"FLAGS"=>[:Seen, :Deleted]}>, \\
     #<Net::IMAP::FetchData seqno=7, attr={"FLAGS"=>[:Seen, :Deleted]}>, \\
     #<Net::IMAP::FetchData seqno=8, attr={"FLAGS"=>[:Seen, :Deleted]}>]

# File lib/net/imap.rb, line 822
def store(set, attr, flags)
  return store_internal("STORE", set, attr, flags)
end
subscribe(mailbox) click to toggle source

Sends a SUBSCRIBE command to add the specified mailbox name to the server's set of “active” or “subscribed” mailboxes as returned by lsub().

A Net::IMAP::NoResponseError is raised if mailbox cannot be subscribed to, for instance because it does not exist.

# File lib/net/imap.rb, line 504
def subscribe(mailbox)
  send_command("SUBSCRIBE", mailbox)
end
thread(algorithm, search_keys, charset) click to toggle source

As for search(), but returns message sequence numbers in threaded format, as a Net::IMAP::ThreadMember tree. The supported algorithms are:

ORDEREDSUBJECT

split into single-level threads according to subject, ordered by date.

REFERENCES

split into threads by parent/child relationships determined by which message is a reply to which.

Unlike search(), charset is a required argument. US-ASCII and UTF-8 are sample values.

See [SORT-THREAD-EXT] for more details.

# File lib/net/imap.rb, line 896
def thread(algorithm, search_keys, charset)
  return thread_internal("THREAD", algorithm, search_keys, charset)
end
uid_copy(set, mailbox) click to toggle source

As for copy(), but set contains unique identifiers.

# File lib/net/imap.rb, line 840
def uid_copy(set, mailbox)
  copy_internal("UID COPY", set, mailbox)
end
uid_fetch(set, attr) click to toggle source

As for fetch(), but set contains unique identifiers.

# File lib/net/imap.rb, line 804
def uid_fetch(set, attr)
  return fetch_internal("UID FETCH", set, attr)
end
uid_search(keys, charset = nil) click to toggle source

As for search(), but returns unique identifiers.

# File lib/net/imap.rb, line 772
def uid_search(keys, charset = nil)
  return search_internal("UID SEARCH", keys, charset)
end
uid_sort(sort_keys, search_keys, charset) click to toggle source

As for sort(), but returns an array of unique identifiers.

# File lib/net/imap.rb, line 858
def uid_sort(sort_keys, search_keys, charset)
  return sort_internal("UID SORT", sort_keys, search_keys, charset)
end
uid_store(set, attr, flags) click to toggle source

As for store(), but set contains unique identifiers.

# File lib/net/imap.rb, line 827
def uid_store(set, attr, flags)
  return store_internal("UID STORE", set, attr, flags)
end
uid_thread(algorithm, search_keys, charset) click to toggle source

As for thread(), but returns unique identifiers instead of message sequence numbers.

# File lib/net/imap.rb, line 902
def uid_thread(algorithm, search_keys, charset)
  return thread_internal("UID THREAD", algorithm, search_keys, charset)
end
unsubscribe(mailbox) click to toggle source

Sends a UNSUBSCRIBE command to remove the specified mailbox name from the server's set of “active” or “subscribed” mailboxes.

A Net::IMAP::NoResponseError is raised if mailbox cannot be unsubscribed from, for instance because the client is not currently subscribed to it.

# File lib/net/imap.rb, line 514
def unsubscribe(mailbox)
  send_command("UNSUBSCRIBE", mailbox)
end
xlist(refname, mailbox) click to toggle source

Sends a XLIST command, and returns a subset of names from the complete set of all names available to the client. refname provides a context (for instance, a base directory in a directory-based mailbox hierarchy). mailbox specifies a mailbox or (via wildcards) mailboxes under that context. Two wildcards may be used in mailbox: '*', which matches all characters including the hierarchy delimiter (for instance, '/' on a UNIX-hosted directory-based mailbox hierarchy); and '%', which matches all characters except the hierarchy delimiter.

If refname is empty, mailbox is used directly to determine which mailboxes to match. If mailbox is empty, the root name of refname and the hierarchy delimiter are returned.

The XLIST command is like the LIST command except that the flags returned refer to the function of the folder/mailbox, e.g. :Sent

The return value is an array of +Net::IMAP::MailboxList+. For example:

imap.create("foo/bar")
imap.create("foo/baz")
p imap.xlist("", "foo/%")
#=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim="/", name="foo/">, \\
     #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim="/", name="foo/bar">, \\
     #<Net::IMAP::MailboxList attr=[:Noinferiors], delim="/", name="foo/baz">]

# File lib/net/imap.rb, line 572
def xlist(refname, mailbox)
  synchronize do
    send_command("XLIST", refname, mailbox)
    return @responses.delete("XLIST")
  end
end


class Net::IMAP::BadResponseError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::BadResponseError

Error raised upon a “BAD” response from the server, indicating that the client command violated the IMAP protocol, or an internal server failure has occurred.

In Files

  • lib/net/imap.rb

Parent

Net::IMAP::ResponseError


class Net::IMAP::BodyTypeAttachment - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::BodyTypeAttachment

Net::IMAP::BodyTypeAttachment represents attachment body structures of messages.

Fields:

media_type

Returns the content media type name.

subtype

Returns nil.

param

Returns a hash that represents parameters.

multipart?

Returns false.

In Files

  • lib/net/imap.rb

Parent

Struct.new(:media_type, :subtype, :param)

Public Instance Methods

multipart?() click to toggle source
# File lib/net/imap.rb, line 1990
def multipart?
  return false
end


class Net::IMAP::BodyTypeBasic - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::BodyTypeBasic

Net::IMAP::BodyTypeBasic represents basic body structures of messages.

Fields:

media_type

Returns the content media type name as defined in [MIME-IMB].

subtype

Returns the content subtype name as defined in [MIME-IMB].

param

Returns a hash that represents parameters as defined in [MIME-IMB].

content_id

Returns a string giving the content id as defined in [MIME-IMB].

description

Returns a string giving the content description as defined in [MIME-IMB].

encoding

Returns a string giving the content transfer encoding as defined in [MIME-IMB].

size

Returns a number giving the size of the body in octets.

md5

Returns a string giving the body MD5 value as defined in [MD5].

disposition

Returns a Net::IMAP::ContentDisposition object giving the content disposition.

language

Returns a string or an array of strings giving the body language value as defined in [LANGUAGE-TAGS].

extension

Returns extension data.

multipart?

Returns false.

In Files

  • lib/net/imap.rb

Parent

Struct.new(:media_type, :subtype, :param, :content_id, :description, :encoding, :size, :md5, :disposition, :language, :extension)

Public Instance Methods

media_subtype() click to toggle source

Obsolete: use subtype instead. Calling this will generate a warning message to stderr, then return the value of subtype.

# File lib/net/imap.rb, line 1910
def media_subtype
  $stderr.printf("warning: media_subtype is obsolete.\n")
  $stderr.printf("         use subtype instead.\n")
  return subtype
end
multipart?() click to toggle source
# File lib/net/imap.rb, line 1903
def multipart?
  return false
end


class Net::IMAP::BodyTypeExtension - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::BodyTypeExtension

In Files

  • lib/net/imap.rb

Parent

Struct.new(:media_type, :subtype, :params, :content_id, :description, :encoding, :size)

Public Instance Methods

multipart?() click to toggle source
# File lib/net/imap.rb, line 2039
def multipart?
  return false
end


class Net::IMAP::BodyTypeMessage - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::BodyTypeMessage

Net::IMAP::BodyTypeMessage represents MESSAGE/RFC822 body structures of messages.

Fields:

envelope

Returns a Net::IMAP::Envelope giving the envelope structure.

body

Returns an object giving the body structure.

And Net::IMAP::BodyTypeMessage has all methods of Net::IMAP::BodyTypeText.

In Files

  • lib/net/imap.rb

Parent

Struct.new(:media_type, :subtype, :param, :content_id, :description, :encoding, :size, :envelope, :body, :lines, :md5, :disposition, :language, :extension)

Public Instance Methods

media_subtype() click to toggle source

Obsolete: use subtype instead. Calling this will generate a warning message to stderr, then return the value of subtype.

# File lib/net/imap.rb, line 1968
def media_subtype
  $stderr.printf("warning: media_subtype is obsolete.\n")
  $stderr.printf("         use subtype instead.\n")
  return subtype
end
multipart?() click to toggle source
# File lib/net/imap.rb, line 1961
def multipart?
  return false
end


class Net::IMAP::BodyTypeMultipart - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::BodyTypeMultipart

Net::IMAP::BodyTypeMultipart represents multipart body structures of messages.

Fields:

media_type

Returns the content media type name as defined in [MIME-IMB].

subtype

Returns the content subtype name as defined in [MIME-IMB].

parts

Returns multiple parts.

param

Returns a hash that represents parameters as defined in [MIME-IMB].

disposition

Returns a Net::IMAP::ContentDisposition object giving the content disposition.

language

Returns a string or an array of strings giving the body language value as defined in [LANGUAGE-TAGS].

extension

Returns extension data.

multipart?

Returns true.

In Files

  • lib/net/imap.rb

Parent

Struct.new(:media_type, :subtype, :parts, :param, :disposition, :language, :extension)

Public Instance Methods

media_subtype() click to toggle source

Obsolete: use subtype instead. Calling this will generate a warning message to stderr, then return the value of subtype.

# File lib/net/imap.rb, line 2029
def media_subtype
  $stderr.printf("warning: media_subtype is obsolete.\n")
  $stderr.printf("         use subtype instead.\n")
  return subtype
end
multipart?() click to toggle source
# File lib/net/imap.rb, line 2022
def multipart?
  return true
end


class Net::IMAP::BodyTypeText - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::BodyTypeText

Net::IMAP::BodyTypeText represents TEXT body structures of messages.

Fields:

lines

Returns the size of the body in text lines.

And Net::IMAP::BodyTypeText has all fields of Net::IMAP::BodyTypeBasic.

In Files

  • lib/net/imap.rb

Parent

Struct.new(:media_type, :subtype, :param, :content_id, :description, :encoding, :size, :lines, :md5, :disposition, :language, :extension)

Public Instance Methods

media_subtype() click to toggle source

Obsolete: use subtype instead. Calling this will generate a warning message to stderr, then return the value of subtype.

# File lib/net/imap.rb, line 1938
def media_subtype
  $stderr.printf("warning: media_subtype is obsolete.\n")
  $stderr.printf("         use subtype instead.\n")
  return subtype
end
multipart?() click to toggle source
# File lib/net/imap.rb, line 1931
def multipart?
  return false
end


class Net::IMAP::ByeResponseError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::ByeResponseError

Error raised upon a “BYE” response from the server, indicating that the client is not being allowed to login, or has been timed out due to inactivity.

In Files

  • lib/net/imap.rb

Parent

Net::IMAP::ResponseError


class Net::IMAP::CramMD5Authenticator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::CramMD5Authenticator

Authenticator for the “CRAM-MD5” authentication type. See authenticate().

In Files

  • lib/net/imap.rb

Parent

Object

Public Class Methods

new(user, password) click to toggle source
# File lib/net/imap.rb, line 3427
def initialize(user, password)
  @user = user
  @password = password
end

Public Instance Methods

process(challenge) click to toggle source
# File lib/net/imap.rb, line 3420
def process(challenge)
  digest = hmac_md5(challenge, @password)
  return @user + " " + digest
end


class Net::IMAP::DataFormatError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::DataFormatError

Error raised when data is in the incorrect format.

In Files

  • lib/net/imap.rb

Parent

Net::IMAP::Error


class Net::IMAP::DigestMD5Authenticator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::DigestMD5Authenticator

Authenticator for the “DIGEST-MD5” authentication type. See authenticate().

In Files

  • lib/net/imap.rb

Parent

Object

Constants

STAGE_ONE
STAGE_TWO

Public Class Methods

new(user, password, authname = nil) click to toggle source
# File lib/net/imap.rb, line 3519
def initialize(user, password, authname = nil)
  @user, @password, @authname = user, password, authname
  @nc, @stage = {}, STAGE_ONE
end

Public Instance Methods

process(challenge) click to toggle source
# File lib/net/imap.rb, line 3454
def process(challenge)
  case @stage
  when STAGE_ONE
    @stage = STAGE_TWO
    sparams = {}
    c = StringScanner.new(challenge)
    while c.scan(/(?:\s*,)?\s*(\w+)=("(?:[^\"]+|\.)*"|[^,]+)\s*/)
      k, v = c[1], c[2]
      if v =~ /^"(.*)"$/
        v = $1
        if v =~ /,/
          v = v.split(',')
        end
      end
      sparams[k] = v
    end

    raise DataFormatError, "Bad Challenge: '#{challenge}'" unless c.rest.size == 0
    raise Error, "Server does not support auth (qop = #{sparams['qop'].join(',')})" unless sparams['qop'].include?("auth")

    response = {
      :nonce => sparams['nonce'],
      :username => @user,
      :realm => sparams['realm'],
      :cnonce => Digest::MD5.hexdigest("%.15f:%.15f:%d" % [Time.now.to_f, rand, Process.pid.to_s]),
      :'digest-uri' => 'imap/' + sparams['realm'],
      :qop => 'auth',
      :maxbuf => 65535,
      :nc => "%08d" % nc(sparams['nonce']),
      :charset => sparams['charset'],
    }

    response[:authzid] = @authname unless @authname.nil?

    # now, the real thing
    a0 = Digest::MD5.digest( [ response.values_at(:username, :realm), @password ].join(':') )

    a1 = [ a0, response.values_at(:nonce,:cnonce) ].join(':')
    a1 << ':' + response[:authzid] unless response[:authzid].nil?

    a2 = "AUTHENTICATE:" + response[:'digest-uri']
    a2 << ":00000000000000000000000000000000" if response[:qop] and response[:qop] =~ /^auth-(?:conf|int)$/

    response[:response] = Digest::MD5.hexdigest(
      [
       Digest::MD5.hexdigest(a1),
       response.values_at(:nonce, :nc, :cnonce, :qop),
       Digest::MD5.hexdigest(a2)
      ].join(':')
    )

    return response.keys.map {|key| qdval(key.to_s, response[key]) }.join(',')
  when STAGE_TWO
    @stage = nil
    # if at the second stage, return an empty string
    if challenge =~ /rspauth=/
      return ''
    else
      raise ResponseParseError, challenge
    end
  else
    raise ResponseParseError, challenge
  end
end


class Net::IMAP::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::Error

Superclass of IMAP errors.

In Files

  • lib/net/imap.rb

Parent

StandardError


class Net::IMAP::FlagCountError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::FlagCountError

Error raised when too many flags are interned to symbols.

In Files

  • lib/net/imap.rb

Parent

Net::IMAP::Error


class Net::IMAP::LoginAuthenticator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::LoginAuthenticator

Authenticator for the “LOGIN” authentication type. See authenticate().

In Files

  • lib/net/imap.rb

Parent

Object

Constants

STATE_PASSWORD
STATE_USER

Public Class Methods

new(user, password) click to toggle source
# File lib/net/imap.rb, line 3393
def initialize(user, password)
  @user = user
  @password = password
  @state = STATE_USER
end

Public Instance Methods

process(data) click to toggle source
# File lib/net/imap.rb, line 3378
def process(data)
  case @state
  when STATE_USER
    @state = STATE_PASSWORD
    return @user
  when STATE_PASSWORD
    return @password
  end
end


class Net::IMAP::NoResponseError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::NoResponseError

Error raised upon a “NO” response from the server, indicating that the client command could not be completed successfully.

In Files

  • lib/net/imap.rb

Parent

Net::IMAP::ResponseError


class Net::IMAP::PlainAuthenticator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::PlainAuthenticator

Authenticator for the “PLAIN” authentication type. See authenticate().

In Files

  • lib/net/imap.rb

Parent

Object

Public Class Methods

new(user, password) click to toggle source
# File lib/net/imap.rb, line 3410
def initialize(user, password)
  @user = user
  @password = password
end

Public Instance Methods

process(data) click to toggle source
# File lib/net/imap.rb, line 3404
def process(data)
  return "\00##{@user}\00##{@password}"
end


class Net::IMAP::ResponseError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::ResponseError

Superclass of all errors used to encapsulate “fail” responses from the server.

In Files

  • lib/net/imap.rb

Parent

Net::IMAP::Error

Attributes

response[RW]

The response that caused this error

Public Class Methods

new(response) click to toggle source
# File lib/net/imap.rb, line 3570
def initialize(response)
  @response = response

  super @response.data.text
end


class Net::IMAP::ResponseParseError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::IMAP::ResponseParseError

Error raised when a response from the server is non-parseable.

In Files

  • lib/net/imap.rb

Parent

Net::IMAP::Error


class Net::OpenTimeout - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::OpenTimeout

OpenTimeout, a subclass of Timeout::Error, is raised if a connection cannot be created within the open_timeout.

In Files

  • lib/net/protocol.rb

Parent

Timeout::Error


class Net::POP3 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::POP3

What is This Library?

This library provides functionality for retrieving email via POP3, the Post Office Protocol version 3. For details of POP3, see [RFC1939] (www.ietf.org/rfc/rfc1939.txt).

Examples

Retrieving Messages

This example retrieves messages from the server and deletes them on the server.

Messages are written to files named 'inbox/1', 'inbox/2', .… Replace 'pop.example.com' with your POP3 server address, and 'YourAccount' and 'YourPassword' with the appropriate account details.

require 'net/pop'

pop = Net::POP3.new('pop.example.com')
pop.start('YourAccount', 'YourPassword')             # (1)
if pop.mails.empty?
  puts 'No mail.'
else
  i = 0
  pop.each_mail do |m|   # or "pop.mails.each ..."   # (2)
    File.open("inbox/#{i}", 'w') do |f|
      f.write m.pop
    end
    m.delete
    i += 1
  end
  puts "#{pop.mails.size} mails popped."
end
pop.finish                                           # (3)

  1. Call #start and start POP session.

  2. Access messages by using #each_mail and/or #mails.

  3. Close POP session by calling #finish or use the block form of start.

Shortened Code

The example above is very verbose. You can shorten the code by using some utility methods. First, the block form of ::start can be used instead of ::new, #start and #finish.

require 'net/pop'

Net::POP3.start('pop.example.com', 110,
                'YourAccount', 'YourPassword') do |pop|
  if pop.mails.empty?
    puts 'No mail.'
  else
    i = 0
    pop.each_mail do |m|   # or "pop.mails.each ..."
      File.open("inbox/#{i}", 'w') do |f|
        f.write m.pop
      end
      m.delete
      i += 1
    end
    puts "#{pop.mails.size} mails popped."
  end
end

#delete_all is an alternative for each_mail and delete.

require 'net/pop'

Net::POP3.start('pop.example.com', 110,
                'YourAccount', 'YourPassword') do |pop|
  if pop.mails.empty?
    puts 'No mail.'
  else
    i = 1
    pop.delete_all do |m|
      File.open("inbox/#{i}", 'w') do |f|
        f.write m.pop
      end
      i += 1
    end
  end
end

And here is an even shorter example.

require 'net/pop'

i = 0
Net::POP3.delete_all('pop.example.com', 110,
                     'YourAccount', 'YourPassword') do |m|
  File.open("inbox/#{i}", 'w') do |f|
    f.write m.pop
  end
  i += 1
end

Memory Space Issues

All the examples above get each message as one big string. This example avoids this.

require 'net/pop'

i = 1
Net::POP3.delete_all('pop.example.com', 110,
                     'YourAccount', 'YourPassword') do |m|
  File.open("inbox/#{i}", 'w') do |f|
    m.pop do |chunk|    # get a message little by little.
      f.write chunk
    end
    i += 1
  end
end

Using APOP

The net/pop library supports APOP authentication. To use APOP, use the Net::APOP class instead of the Net::POP3 class. You can use the utility method, Net::POP3.APOP(). For example:

require 'net/pop'

# Use APOP authentication if $isapop == true
pop = Net::POP3.APOP($is_apop).new('apop.example.com', 110)
pop.start(YourAccount', 'YourPassword') do |pop|
  # Rest of the code is the same.
end

Fetch Only Selected Mail Using 'UIDL' POP Command

If your POP server provides UIDL functionality, you can grab only selected mails from the POP server. e.g.

def need_pop?( id )
  # determine if we need pop this mail...
end

Net::POP3.start('pop.example.com', 110,
                'Your account', 'Your password') do |pop|
  pop.mails.select { |m| need_pop?(m.unique_id) }.each do |m|
    do_something(m.pop)
  end
end

The Net::POPMail#unique_id method returns the unique-id of the message as a String. Normally the unique-id is a hash of the message.

In Files

  • lib/net/pop.rb

Parent

Protocol

Constants

Revision

svn revision of this library

Attributes

address[R]

The address to connect to.

open_timeout[RW]

Seconds to wait until a connection is opened. If the POP3 object cannot open a connection within this time, it raises a Net::OpenTimeout exception. The default value is 30 seconds.

read_timeout[R]

Seconds to wait until reading one block (by one read(1) call). If the POP3 object cannot complete a read() within this time, it raises a Net::ReadTimeout exception. The default value is 60 seconds.

Public Class Methods

APOP(isapop) click to toggle source

Returns the APOP class if isapop is true; otherwise, returns the POP class. For example:

# Example 1
pop = Net::POP3::APOP($is_apop).new(addr, port)

# Example 2
Net::POP3::APOP($is_apop).start(addr, port) do |pop|
  ....
end

# File lib/net/pop.rb, line 238
def POP3.APOP(isapop)
  isapop ? APOP : POP3
end
auth_only(address, port = nil, account = nil, password = nil, isapop = false) click to toggle source

Opens a POP3 session, attempts authentication, and quits.

This method raises POPAuthenticationError if authentication fails.

Example: normal POP3

Net::POP3.auth_only('pop.example.com', 110,
                    'YourAccount', 'YourPassword')

Example: APOP

Net::POP3.auth_only('pop.example.com', 110,
                    'YourAccount', 'YourPassword', true)
# File lib/net/pop.rb, line 305
def POP3.auth_only(address, port = nil,
                   account = nil, password = nil,
                   isapop = false)
  new(address, port, isapop).auth_only account, password
end
certs() click to toggle source

returns the :ca_file or :ca_path from ::ssl_params

# File lib/net/pop.rb, line 377
def POP3.certs
  return @ssl_params[:ca_file] || @ssl_params[:ca_path]
end
create_ssl_params(verify_or_params = {}, certs = nil) click to toggle source

Constructs proper parameters from arguments

# File lib/net/pop.rb, line 337
def POP3.create_ssl_params(verify_or_params = {}, certs = nil)
  begin
    params = verify_or_params.to_hash
  rescue NoMethodError
    params = {}
    params[:verify_mode] = verify_or_params
    if certs
      if File.file?(certs)
        params[:ca_file] = certs
      elsif File.directory?(certs)
        params[:ca_path] = certs
      end
    end
  end
  return params
end
default_pop3_port() click to toggle source

The default port for POP3 connections, port 110

# File lib/net/pop.rb, line 210
def POP3.default_pop3_port
  110
end
default_pop3s_port() click to toggle source

The default port for POP3S connections, port 995

# File lib/net/pop.rb, line 215
def POP3.default_pop3s_port
  995
end
default_port() click to toggle source

returns the port for POP3

# File lib/net/pop.rb, line 205
def POP3.default_port
  default_pop3_port()
end
delete_all(address, port = nil, account = nil, password = nil, isapop = false, &block) click to toggle source

Starts a POP3 session and deletes all messages on the server. If a block is given, each POPMail object is yielded to it before being deleted.

This method raises a POPAuthenticationError if authentication fails.

Example

Net::POP3.delete_all('pop.example.com', 110,
                     'YourAccount', 'YourPassword') do |m|
  file.write m.pop
end

# File lib/net/pop.rb, line 283
def POP3.delete_all(address, port = nil,
                    account = nil, password = nil,
                    isapop = false, &block)
  start(address, port, account, password, isapop) {|pop|
    pop.delete_all(&block)
  }
end
disable_ssl() click to toggle source

Disable SSL for all new instances.

# File lib/net/pop.rb, line 355
def POP3.disable_ssl
  @ssl_params = nil
end
Net::POP.enable_ssl(params = {}) click to toggle source

Enable SSL for all new instances. params is passed to OpenSSL::SSLContext#set_params.

# File lib/net/pop.rb, line 332
def POP3.enable_ssl(*args)
  @ssl_params = create_ssl_params(*args)
end
foreach(address, port = nil, account = nil, password = nil, isapop = false) { |message| ... } click to toggle source

Starts a POP3 session and iterates over each POPMail object, yielding it to the block. This method is equivalent to:

Net::POP3.start(address, port, account, password) do |pop|
  pop.each_mail do |m|
    yield m
  end
end

This method raises a POPAuthenticationError if authentication fails.

Example

Net::POP3.foreach('pop.example.com', 110,
                  'YourAccount', 'YourPassword') do |m|
  file.write m.pop
  m.delete if $DELETE
end

# File lib/net/pop.rb, line 262
def POP3.foreach(address, port = nil,
                 account = nil, password = nil,
                 isapop = false, &block)  # :yields: message
  start(address, port, account, password, isapop) {|pop|
    pop.each_mail(&block)
  }
end
new(addr, port = nil, isapop = false) click to toggle source

Creates a new POP3 object.

address is the hostname or ip address of your POP3 server.

The optional port is the port to connect to.

The optional isapop specifies whether this connection is going to use APOP authentication; it defaults to false.

This method does not open the TCP connection.

# File lib/net/pop.rb, line 417
def initialize(addr, port = nil, isapop = false)
  @address = addr
  @ssl_params = POP3.ssl_params
  @port = port
  @apop = isapop

  @command = nil
  @socket = nil
  @started = false
  @open_timeout = 30
  @read_timeout = 60
  @debug_output = nil

  @mails = nil
  @n_mails = nil
  @n_bytes = nil
end
ssl_params() click to toggle source

returns the SSL Parameters

see also ::enable_ssl

# File lib/net/pop.rb, line 362
def POP3.ssl_params
  return @ssl_params
end
start(address, port = nil, account = nil, password = nil, isapop = false) { |pop| ... } click to toggle source

Creates a new POP3 object and open the connection. Equivalent to

Net::POP3.new(address, port, isapop).start(account, password)

If block is provided, yields the newly-opened POP3 object to it, and automatically closes it at the end of the session.

Example

Net::POP3.start(addr, port, account, password) do |pop|
  pop.each_mail do |m|
    file.write m.pop
    m.delete
  end
end

# File lib/net/pop.rb, line 401
def POP3.start(address, port = nil,
               account = nil, password = nil,
               isapop = false, &block)   # :yield: pop
  new(address, port, isapop).start(account, password, &block)
end
use_ssl?() click to toggle source

returns true if ::ssl_params is set

# File lib/net/pop.rb, line 367
def POP3.use_ssl?
  return !@ssl_params.nil?
end
verify() click to toggle source

returns whether verify_mode is enable from ::ssl_params

# File lib/net/pop.rb, line 372
def POP3.verify
  return @ssl_params[:verify_mode]
end

Public Instance Methods

active?() click to toggle source
Alias for: started?
apop?() click to toggle source

Does this instance use APOP authentication?

# File lib/net/pop.rb, line 436
def apop?
  @apop
end
auth_only(account, password) click to toggle source

Starts a pop3 session, attempts authentication, and quits. This method must not be called while POP3 session is opened. This method raises POPAuthenticationError if authentication fails.

# File lib/net/pop.rb, line 314
def auth_only(account, password)
  raise IOError, 'opening previously opened POP session' if started?
  start(account, password) {
    ;
  }
end
delete_all() { |message| ... } click to toggle source

Deletes all messages on the server.

If called with a block, yields each message in turn before deleting it.

Example

n = 1
pop.delete_all do |m|
  File.open("inbox/#{n}") do |f|
    f.write m.pop
  end
  n += 1
end

This method raises a POPError if an error occurs.

# File lib/net/pop.rb, line 686
def delete_all # :yield: message
  mails().each do |m|
    yield m if block_given?
    m.delete unless m.deleted?
  end
end
disable_ssl() click to toggle source

Disable SSL for all new instances.

# File lib/net/pop.rb, line 463
def disable_ssl
  @ssl_params = nil
end
each() click to toggle source
Alias for: each_mail
each_mail() { |message| ... } click to toggle source

Yields each message to the passed-in block in turn. Equivalent to:

pop3.mails.each do |popmail|
  ....
end

This method raises a POPError if an error occurs.

# File lib/net/pop.rb, line 664
def each_mail(&block)  # :yield: message
  mails().each(&block)
end
Also aliased as: each
Net::POP#enable_ssl(params = {}) click to toggle source

Enables SSL for this instance. Must be called before the connection is established to have any effect. +params+ is port to establish the SSL connection on; Defaults to 995. params (except :port) is passed to OpenSSL::SSLContext#set_params.

# File lib/net/pop.rb, line 452
def enable_ssl(verify_or_params = {}, certs = nil, port = nil)
  begin
    @ssl_params = verify_or_params.to_hash.dup
    @port = @ssl_params.delete(:port) || @port
  rescue NoMethodError
    @ssl_params = POP3.create_ssl_params(verify_or_params, certs)
    @port = port || @port
  end
end
finish() click to toggle source

Finishes a POP3 session and closes TCP connection.

# File lib/net/pop.rb, line 585
def finish
  raise IOError, 'POP session not yet started' unless started?
  do_finish
end
inspect() click to toggle source

Provide human-readable stringification of class state.

# File lib/net/pop.rb, line 468
def inspect
  "#<#{self.class} #{@address}:#{@port} open=#{@started}>"
end
logging(msg) click to toggle source

deguging output for msg

# File lib/net/pop.rb, line 711
def logging(msg)
  @debug_output << msg + "\n" if @debug_output
end
mails() click to toggle source

Returns an array of Net::POPMail objects, representing all the messages on the server. This array is renewed when the session restarts; otherwise, it is fetched from the server the first time this method is called (directly or indirectly) and cached.

This method raises a POPError if an error occurs.

# File lib/net/pop.rb, line 642
def mails
  return @mails.dup if @mails
  if n_mails() == 0
    # some popd raises error for LIST on the empty mailbox.
    @mails = []
    return []
  end

  @mails = command().list.map {|num, size|
    POPMail.new(num, size, self, command())
  }
  @mails.dup
end
n_bytes() click to toggle source

Returns the total size in bytes of all the messages on the POP server.

# File lib/net/pop.rb, line 630
def n_bytes
  return @n_bytes if @n_bytes
  @n_mails, @n_bytes = command().stat
  @n_bytes
end
n_mails() click to toggle source

Returns the number of messages on the POP server.

# File lib/net/pop.rb, line 623
def n_mails
  return @n_mails if @n_mails
  @n_mails, @n_bytes = command().stat
  @n_mails
end
port() click to toggle source

The port number to connect to.

# File lib/net/pop.rb, line 493
def port
  return @port || (use_ssl? ? POP3.default_pop3s_port : POP3.default_pop3_port)
end
read_timeout=(sec) click to toggle source

Set the read timeout.

# File lib/net/pop.rb, line 508
def read_timeout=(sec)
  @command.socket.read_timeout = sec if @command
  @read_timeout = sec
end
reset() click to toggle source

Resets the session. This clears all “deleted” marks from messages.

This method raises a POPError if an error occurs.

# File lib/net/pop.rb, line 696
def reset
  command().rset
  mails().each do |m|
    m.instance_eval {
      @deleted = false
    }
  end
end
set_debug_output(arg) click to toggle source

WARNING: This method causes a serious security hole. Use this method only for debugging.

Set an output stream for debugging.

Example

pop = Net::POP.new(addr, port)
pop.set_debug_output $stderr
pop.start(account, passwd) do |pop|
  ....
end

# File lib/net/pop.rb, line 485
def set_debug_output(arg)
  @debug_output = arg
end
start(account, password) { |pop| ... } click to toggle source

Starts a POP3 session.

When called with block, gives a POP3 object to the block and closes the session after block call finishes.

This method raises a POPAuthenticationError if authentication fails.

# File lib/net/pop.rb, line 526
def start(account, password) # :yield: pop
  raise IOError, 'POP session already started' if @started
  if block_given?
    begin
      do_start account, password
      return yield(self)
    ensure
      do_finish
    end
  else
    do_start account, password
    return self
  end
end
started?() click to toggle source

true if the POP3 session has started.

# File lib/net/pop.rb, line 514
def started?
  @started
end
Also aliased as: active?
use_ssl?() click to toggle source

does this instance use SSL?

# File lib/net/pop.rb, line 441
def use_ssl?
  return !@ssl_params.nil?
end


class Net::POPAuthenticationError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::POPAuthenticationError

POP3 authentication error.

In Files

  • lib/net/pop.rb

Parent

ProtoAuthError


class Net::POPBadResponse - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::POPBadResponse

Unexpected response from the server.

In Files

  • lib/net/pop.rb

Parent

Net::POPError


class Net::POPError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::POPError

Non-authentication POP3 protocol error (reply code “-ERR”, except authentication).

In Files

  • lib/net/pop.rb

Parent

ProtocolError


class Net::POPMail - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::POPMail

This class represents a message which exists on the POP server. Instances of this class are created by the POP3 class; they should not be directly created by the user.

In Files

  • lib/net/pop.rb

Parent

Object

Attributes

length[R]

The length of the message in octets.

number[R]

The sequence number of the message on the server.

size[R]

The length of the message in octets.

Public Instance Methods

all( dest = '' ) click to toggle source
Alias for: pop
delete() click to toggle source

Marks a message for deletion on the server. Deletion does not actually occur until the end of the session; deletion may be cancelled for all marked messages by calling Net::POP3#reset.

This method raises a POPError if an error occurs.

Example

POP3.start('pop.example.com', 110,
           'YourAccount, 'YourPassword') do |pop|
  n = 1
  pop.mails.each do |popmail|
    File.open("inbox/#{n}", 'w') do |f|
      f.write popmail.pop
    end
    popmail.delete         ####
    n += 1
  end
end

# File lib/net/pop.rb, line 857
def delete
  @command.dele @number
  @deleted = true
end
Also aliased as: delete!
delete!() click to toggle source
Alias for: delete
deleted?() click to toggle source

True if the mail has been deleted.

# File lib/net/pop.rb, line 865
def deleted?
  @deleted
end
header(dest = '') click to toggle source

Fetches the message header.

The optional dest argument is obsolete.

This method raises a POPError if an error occurs.

# File lib/net/pop.rb, line 833
def header(dest = '')
  top(0, dest)
end
inspect() click to toggle source

Provide human-readable stringification of class state.

# File lib/net/pop.rb, line 759
def inspect
  "#<#{self.class} #{@number}#{@deleted ? ' deleted' : ''}>"
end
mail( dest = '' ) click to toggle source
Alias for: pop
pop( dest = '' ) { |message_chunk| ... } click to toggle source

This method fetches the message. If called with a block, the message is yielded to the block one chunk at a time. If called without a block, the message is returned as a String. The optional dest argument will be prepended to the returned String; this argument is essentially obsolete.

Example without block

POP3.start('pop.example.com', 110,
           'YourAccount, 'YourPassword') do |pop|
  n = 1
  pop.mails.each do |popmail|
    File.open("inbox/#{n}", 'w') do |f|
      f.write popmail.pop
    end
    popmail.delete
    n += 1
  end
end

Example with block

POP3.start('pop.example.com', 110,
           'YourAccount, 'YourPassword') do |pop|
  n = 1
  pop.mails.each do |popmail|
    File.open("inbox/#{n}", 'w') do |f|
      popmail.pop do |chunk|            ####
        f.write chunk
      end
    end
    n += 1
  end
end

This method raises a POPError if an error occurs.

# File lib/net/pop.rb, line 801
def pop( dest = '', &block ) # :yield: message_chunk
  if block_given?
    @command.retr(@number, &block)
    nil
  else
    @command.retr(@number) do |chunk|
      dest << chunk
    end
    dest
  end
end
Also aliased as: all, mail
top(lines, dest = '') click to toggle source

Fetches the message header and lines lines of body.

The optional dest argument is obsolete.

This method raises a POPError if an error occurs.

# File lib/net/pop.rb, line 821
def top(lines, dest = '')
  @command.top(@number, lines) do |chunk|
    dest << chunk
  end
  dest
end
uidl() click to toggle source
Alias for: unique_id
unique_id() click to toggle source

Returns the unique-id of the message. Normally the unique-id is a hash string of the message.

This method raises a POPError if an error occurs.

# File lib/net/pop.rb, line 873
def unique_id
  return @uid if @uid
  @pop.set_all_uids
  @uid
end
Also aliased as: uidl


class Net::ProtoAuthError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::ProtoAuthError

In Files

  • lib/net/protocol.rb

Parent

Net::ProtocolError


class Net::ProtoCommandError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::ProtoCommandError

In Files

  • lib/net/protocol.rb

Parent

Net::ProtocolError


class Net::ProtoFatalError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::ProtoFatalError

In Files

  • lib/net/protocol.rb

Parent

Net::ProtocolError


class Net::ProtoRetriableError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::ProtoRetriableError

In Files

  • lib/net/protocol.rb

Parent

Net::ProtocolError


class Net::ProtoServerError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::ProtoServerError

In Files

  • lib/net/protocol.rb

Parent

Net::ProtocolError


class Net::ProtoSyntaxError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::ProtoSyntaxError

In Files

  • lib/net/protocol.rb

Parent

Net::ProtocolError


class Net::ProtoUnknownError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::ProtoUnknownError

In Files

  • lib/net/protocol.rb

Parent

Net::ProtocolError


class Net::ProtocolError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::ProtocolError

In Files

  • lib/net/protocol.rb

Parent

StandardError


class Net::ReadTimeout - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::ReadTimeout

ReadTimeout, a subclass of Timeout::Error, is raised if a chunk of the response cannot be read within the read_timeout.

In Files

  • lib/net/protocol.rb

Parent

Timeout::Error


class Net::SMTP - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::SMTP

What is This Library?

This library provides functionality to send internet mail via SMTP, the Simple Mail Transfer Protocol. For details of SMTP itself, see [RFC2821] (www.ietf.org/rfc/rfc2821.txt).

What is This Library NOT?

This library does NOT provide functions to compose internet mails. You must create them by yourself. If you want better mail support, try RubyMail or TMail or search for alternatives in RubyGems.org or The Ruby Toolbox.

FYI: the official documentation on internet mail is: [RFC2822] (www.ietf.org/rfc/rfc2822.txt).

Examples

Sending Messages

You must open a connection to an SMTP server before sending messages. The first argument is the address of your SMTP server, and the second argument is the port number. Using ::start with a block is the simplest way to do this. This way, the SMTP connection is closed automatically after the block is executed.

require 'net/smtp'
Net::SMTP.start('your.smtp.server', 25) do |smtp|
  # Use the SMTP object smtp only in this block.
end

Replace 'your.smtp.server' with your SMTP server. Normally your system manager or internet provider supplies a server for you.

Then you can send messages.

msgstr = <<END_OF_MESSAGE
From: Your Name <your@mail.address>
To: Destination Address <someone@example.com>
Subject: test message
Date: Sat, 23 Jun 2001 16:26:43 +0900
Message-Id: <unique.message.id.string@example.com>

This is a test message.
END_OF_MESSAGE

require 'net/smtp'
Net::SMTP.start('your.smtp.server', 25) do |smtp|
  smtp.send_message msgstr,
                    'your@mail.address',
                    'his_address@example.com'
end

Closing the Session

You MUST close the SMTP session after sending messages, by calling the finish method:

# using SMTP#finish
smtp = Net::SMTP.start('your.smtp.server', 25)
smtp.send_message msgstr, 'from@address', 'to@address'
smtp.finish

You can also use the block form of ::start/#start. This closes the SMTP session automatically:

# using block form of SMTP.start
Net::SMTP.start('your.smtp.server', 25) do |smtp|
  smtp.send_message msgstr, 'from@address', 'to@address'
end

I strongly recommend this scheme. This form is simpler and more robust.

HELO domain

In almost all situations, you must provide a third argument to ::start/#start. This is the domain name which you are on (the host to send mail from). It is called the “HELO domain”. The SMTP server will judge whether it should send or reject the SMTP session by inspecting the HELO domain.

Net::SMTP.start('your.smtp.server', 25,
                'mail.from.domain') { |smtp| ... }

SMTP Authentication

The Net::SMTP class supports three authentication schemes; PLAIN, LOGIN and CRAM MD5. (SMTP Authentication: [RFC2554]) To use SMTP authentication, pass extra arguments to ::start/#start.

# PLAIN
Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
                'Your Account', 'Your Password', :plain)
# LOGIN
Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
                'Your Account', 'Your Password', :login)

# CRAM MD5
Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
                'Your Account', 'Your Password', :cram_md5)

In Files

  • lib/net/smtp.rb

Parent

Object

Constants

CRAM_BUFSIZE
DEFAULT_AUTH_TYPE

Authentication

IMASK
OMASK
Revision

Attributes

address[R]

The address of the SMTP server to connect to.

esmtp[RW]

Set whether to use ESMTP or not. This should be done before calling start. Note that if start is called in ESMTP mode, and the connection fails due to a ProtocolError, the SMTP object will automatically switch to plain SMTP mode and retry (but not vice versa).

esmtp?[RW]

Set whether to use ESMTP or not. This should be done before calling start. Note that if start is called in ESMTP mode, and the connection fails due to a ProtocolError, the SMTP object will automatically switch to plain SMTP mode and retry (but not vice versa).

open_timeout[RW]

Seconds to wait while attempting to open a connection. If the connection cannot be opened within this time, a Net::OpenTimeout is raised. The default value is 30 seconds.

port[R]

The port number of the SMTP server to connect to.

read_timeout[R]

Seconds to wait while reading one block (by one read(2) call). If the read(2) call does not complete within this time, a Net::ReadTimeout is raised. The default value is 60 seconds.

Public Class Methods

default_port() click to toggle source

The default SMTP port number, 25.

# File lib/net/smtp.rb, line 177
def SMTP.default_port
  25
end
default_ssl_context() click to toggle source
# File lib/net/smtp.rb, line 195
def SMTP.default_ssl_context
  OpenSSL::SSL::SSLContext.new
end
default_ssl_port() click to toggle source
Alias for: default_tls_port
default_submission_port() click to toggle source

The default mail submission port number, 587.

# File lib/net/smtp.rb, line 182
def SMTP.default_submission_port
  587
end
default_tls_port() click to toggle source

The default SMTPS port number, 465.

# File lib/net/smtp.rb, line 187
def SMTP.default_tls_port
  465
end
Also aliased as: default_ssl_port
new(address, port = nil) click to toggle source

Creates a new Net::SMTP object.

address is the hostname or ip address of your SMTP server. port is the port to connect to; it defaults to port 25.

This method does not open the TCP connection. You can use ::start instead of ::new if you want to do everything at once. Otherwise, follow ::new with #start.

# File lib/net/smtp.rb, line 210
def initialize(address, port = nil)
  @address = address
  @port = (port || SMTP.default_port)
  @esmtp = true
  @capabilities = nil
  @socket = nil
  @started = false
  @open_timeout = 30
  @read_timeout = 60
  @error_occurred = false
  @debug_output = nil
  @tls = false
  @starttls = false
  @ssl_context = nil
end
start(address, port = nil, helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... } click to toggle source

Creates a new Net::SMTP object and connects to the server.

This method is equivalent to:

Net::SMTP.new(address, port).start(helo_domain, account, password, authtype)

Example

Net::SMTP.start('your.smtp.server') do |smtp|
  smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
end

Block Usage

If called with a block, the newly-opened Net::SMTP object is yielded to the block, and automatically closed when the block finishes. If called without a block, the newly-opened Net::SMTP object is returned to the caller, and it is the caller's responsibility to close it when finished.

Parameters

address is the hostname or ip address of your smtp server.

port is the port to connect to; it defaults to port 25.

helo is the HELO domain provided by the client to the server (see overview comments); it defaults to 'localhost'.

The remaining arguments are used for SMTP authentication, if required or desired. user is the account name; secret is your password or other authentication token; and authtype is the authentication type, one of :plain, :login, or :cram_md5. See the discussion of SMTP Authentication in the overview notes.

Errors

This method may raise:

  • Net::SMTPAuthenticationError

  • Net::SMTPServerBusy

  • Net::SMTPSyntaxError

  • Net::SMTPFatalError

  • Net::SMTPUnknownError

  • Net::OpenTimeout

  • Net::ReadTimeout

  • IOError

# File lib/net/smtp.rb, line 454
def SMTP.start(address, port = nil, helo = 'localhost',
               user = nil, secret = nil, authtype = nil,
               &block)   # :yield: smtp
  new(address, port).start(helo, user, secret, authtype, &block)
end

Public Instance Methods

auth_cram_md5(user, secret) click to toggle source
# File lib/net/smtp.rb, line 755
def auth_cram_md5(user, secret)
  check_auth_args user, secret
  res = critical {
    res0 = get_response('AUTH CRAM-MD5')
    check_auth_continue res0
    crammed = cram_md5_response(secret, res0.cram_md5_challenge)
    get_response(base64_encode("#{user} #{crammed}"))
  }
  check_auth_response res
  res
end
auth_login(user, secret) click to toggle source
# File lib/net/smtp.rb, line 744
def auth_login(user, secret)
  check_auth_args user, secret
  res = critical {
    check_auth_continue get_response('AUTH LOGIN')
    check_auth_continue get_response(base64_encode(user))
    get_response(base64_encode(secret))
  }
  check_auth_response res
  res
end
auth_plain(user, secret) click to toggle source
# File lib/net/smtp.rb, line 735
def auth_plain(user, secret)
  check_auth_args user, secret
  res = critical {
    get_response('AUTH PLAIN ' + base64_encode("\00##{user}\00##{secret}"))
  }
  check_auth_response res
  res
end
authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE) click to toggle source
# File lib/net/smtp.rb, line 729
def authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE)
  check_auth_method authtype
  check_auth_args user, secret
  send auth_method(authtype), user, secret
end
capable_auth_types() click to toggle source

Returns supported authentication methods on this server. You cannot get valid value before opening SMTP session.

# File lib/net/smtp.rb, line 282
def capable_auth_types
  return [] unless @capabilities
  return [] unless @capabilities['AUTH']
  @capabilities['AUTH']
end
capable_cram_md5_auth?() click to toggle source

true if server advertises AUTH CRAM-MD5. You cannot get valid value before opening SMTP session.

# File lib/net/smtp.rb, line 269
def capable_cram_md5_auth?
  auth_capable?('CRAM-MD5')
end
capable_login_auth?() click to toggle source

true if server advertises AUTH LOGIN. You cannot get valid value before opening SMTP session.

# File lib/net/smtp.rb, line 263
def capable_login_auth?
  auth_capable?('LOGIN')
end
capable_plain_auth?() click to toggle source

true if server advertises AUTH PLAIN. You cannot get valid value before opening SMTP session.

# File lib/net/smtp.rb, line 257
def capable_plain_auth?
  auth_capable?('PLAIN')
end
capable_starttls?() click to toggle source

true if server advertises STARTTLS. You cannot get valid value before opening SMTP session.

# File lib/net/smtp.rb, line 245
def capable_starttls?
  capable?('STARTTLS')
end
data(msgstr = nil) { |stream| ... } click to toggle source

This method sends a message. If msgstr is given, sends it as a message. If block is given, yield a message writer stream. You must write message before the block is closed.

# Example 1 (by string)
smtp.data("From: john@example.com
To: betty@example.com
Subject: I found a bug

Check vm.c:58879.
")

# Example 2 (by block)
smtp.data {|f|
  f.puts "From: john@example.com"
  f.puts "To: betty@example.com"
  f.puts "Subject: I found a bug"
  f.puts ""
  f.puts "Check vm.c:58879."
}

# File lib/net/smtp.rb, line 889
def data(msgstr = nil, &block)   #:yield: stream
  if msgstr and block
    raise ArgumentError, "message and block are exclusive"
  end
  unless msgstr or block
    raise ArgumentError, "message or block is required"
  end
  res = critical {
    check_continue get_response('DATA')
    if msgstr
      @socket.write_message msgstr
    else
      @socket.write_message_by_block(&block)
    end
    recv_response()
  }
  check_response res
  res
end
debug_output=(arg) click to toggle source

WARNING: This method causes serious security holes. Use this method for only debugging.

Set an output stream for debug logging. You must call this before start.

# example
smtp = Net::SMTP.new(addr, port)
smtp.set_debug_output $stderr
smtp.start do |smtp|
  ....
end

# File lib/net/smtp.rb, line 395
def debug_output=(arg)
  @debug_output = arg
end
Also aliased as: set_debug_output
disable_ssl() click to toggle source
Alias for: disable_tls
disable_starttls() click to toggle source

Disables SMTP/TLS (STARTTLS) for this object. Must be called before the connection is established to have any effect.

# File lib/net/smtp.rb, line 353
def disable_starttls
  @starttls = false
  @ssl_context = nil
end
disable_tls() click to toggle source

Disables SMTP/TLS for this object. Must be called before the connection is established to have any effect.

# File lib/net/smtp.rb, line 309
def disable_tls
  @tls = false
  @ssl_context = nil
end
Also aliased as: disable_ssl
ehlo(domain) click to toggle source
# File lib/net/smtp.rb, line 827
def ehlo(domain)
  getok("EHLO #{domain}")
end
enable_ssl(context = SMTP.default_ssl_context) click to toggle source
Alias for: enable_tls
enable_starttls(context = SMTP.default_ssl_context) click to toggle source

Enables SMTP/TLS (STARTTLS) for this object. context is a OpenSSL::SSL::SSLContext object.

# File lib/net/smtp.rb, line 335
def enable_starttls(context = SMTP.default_ssl_context)
  raise 'openssl library not installed' unless defined?(OpenSSL)
  raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
  @starttls = :always
  @ssl_context = context
end
enable_starttls_auto(context = SMTP.default_ssl_context) click to toggle source

Enables SMTP/TLS (STARTTLS) for this object if server accepts. context is a OpenSSL::SSL::SSLContext object.

# File lib/net/smtp.rb, line 344
def enable_starttls_auto(context = SMTP.default_ssl_context)
  raise 'openssl library not installed' unless defined?(OpenSSL)
  raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
  @starttls = :auto
  @ssl_context = context
end
enable_tls(context = SMTP.default_ssl_context) click to toggle source

Enables SMTP/TLS (SMTPS: SMTP over direct TLS connection) for this object. Must be called before the connection is established to have any effect. context is a OpenSSL::SSL::SSLContext object.

# File lib/net/smtp.rb, line 298
def enable_tls(context = SMTP.default_ssl_context)
  raise 'openssl library not installed' unless defined?(OpenSSL)
  raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @starttls
  @tls = true
  @ssl_context = context
end
Also aliased as: enable_ssl
finish() click to toggle source

Finishes the SMTP session and closes TCP connection. Raises IOError if not started.

# File lib/net/smtp.rb, line 533
def finish
  raise IOError, 'not yet started' unless started?
  do_finish
end
helo(domain) click to toggle source
# File lib/net/smtp.rb, line 823
def helo(domain)
  getok("HELO #{domain}")
end
inspect() click to toggle source

Provide human-readable stringification of class state.

# File lib/net/smtp.rb, line 227
def inspect
  "#<#{self.class} #{@address}:#{@port} started=#{@started}>"
end
mailfrom(from_addr) click to toggle source
# File lib/net/smtp.rb, line 831
def mailfrom(from_addr)
  if $SAFE > 0
    raise SecurityError, 'tainted from_addr' if from_addr.tainted?
  end
  getok("MAIL FROM:<#{from_addr}>")
end
open_message_stream(from_addr, *to_addrs) { |stream| ... } click to toggle source

Opens a message writer stream and gives it to the block. The stream is valid only in the block, and has these methods:

puts(str = '')

outputs STR and CR LF.

print(str)

outputs STR.

printf(fmt, *args)

outputs sprintf(fmt,*args).

write(str)

outputs STR and returns the length of written bytes.

<<(str)

outputs STR and returns self.

If a single CR (“r”) or LF (“n”) is found in the message, it is converted to the CR LF pair. You cannot send a binary message with this method.

Parameters

from_addr is a String representing the source mail address.

to_addr is a String or Strings or Array of Strings, representing the destination mail address or addresses.

Example

Net::SMTP.start('smtp.example.com', 25) do |smtp|
  smtp.open_message_stream('from@example.com', ['dest@example.com']) do |f|
    f.puts 'From: from@example.com'
    f.puts 'To: dest@example.com'
    f.puts 'Subject: test message'
    f.puts
    f.puts 'This is a test message.'
  end
end

Errors

This method may raise:

  • Net::SMTPServerBusy

  • Net::SMTPSyntaxError

  • Net::SMTPFatalError

  • Net::SMTPUnknownError

  • Net::ReadTimeout

  • IOError

# File lib/net/smtp.rb, line 713
def open_message_stream(from_addr, *to_addrs, &block)   # :yield: stream
  raise IOError, 'closed session' unless @socket
  mailfrom from_addr
  rcptto_list(to_addrs) {data(&block)}
end
Also aliased as: ready
quit() click to toggle source
# File lib/net/smtp.rb, line 909
def quit
  getok('QUIT')
end
rcptto(to_addr) click to toggle source
# File lib/net/smtp.rb, line 859
def rcptto(to_addr)
  if $SAFE > 0
    raise SecurityError, 'tainted to_addr' if to_addr.tainted?
  end
  getok("RCPT TO:<#{to_addr}>")
end
rcptto_list(to_addrs) { || ... } click to toggle source
# File lib/net/smtp.rb, line 838
def rcptto_list(to_addrs)
  raise ArgumentError, 'mail destination not given' if to_addrs.empty?
  ok_users = []
  unknown_users = []
  to_addrs.flatten.each do |addr|
    begin
      rcptto addr
    rescue SMTPAuthenticationError
      unknown_users << addr.dump
    else
      ok_users << addr
    end
  end
  raise ArgumentError, 'mail destination not given' if ok_users.empty?
  ret = yield
  unless unknown_users.empty?
    raise SMTPAuthenticationError, "failed to deliver for #{unknown_users.join(', ')}"
  end
  ret
end
read_timeout=(sec) click to toggle source

Set the number of seconds to wait until timing-out a read(2) call.

# File lib/net/smtp.rb, line 376
def read_timeout=(sec)
  @socket.read_timeout = sec if @socket
  @read_timeout = sec
end
ready(from_addr, *to_addrs) click to toggle source
Alias for: open_message_stream
send_mail(msgstr, from_addr, *to_addrs) click to toggle source
Alias for: send_message
send_message(msgstr, from_addr, *to_addrs) click to toggle source

Sends msgstr as a message. Single CR (“r”) and LF (“n”) found in the msgstr, are converted into the CR LF pair. You cannot send a binary message with this method. msgstr should include both the message headers and body.

from_addr is a String representing the source mail address.

to_addr is a String or Strings or Array of Strings, representing the destination mail address or addresses.

Example

Net::SMTP.start('smtp.example.com') do |smtp|
  smtp.send_message msgstr,
                    'from@example.com',
                    ['dest@example.com', 'dest2@example.com']
end

Errors

This method may raise:

  • Net::SMTPServerBusy

  • Net::SMTPSyntaxError

  • Net::SMTPFatalError

  • Net::SMTPUnknownError

  • Net::ReadTimeout

  • IOError

# File lib/net/smtp.rb, line 660
def send_message(msgstr, from_addr, *to_addrs)
  raise IOError, 'closed session' unless @socket
  mailfrom from_addr
  rcptto_list(to_addrs) {data msgstr}
end
Also aliased as: send_mail, sendmail
sendmail(msgstr, from_addr, *to_addrs) click to toggle source
Alias for: send_message
set_debug_output(arg) click to toggle source
Alias for: debug_output=
ssl?() click to toggle source
Alias for: tls?
start(helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... } click to toggle source

Opens a TCP connection and starts the SMTP session.

Parameters

helo is the HELO domain that you'll dispatch mails from; see the discussion in the overview notes.

If both of user and secret are given, SMTP authentication will be attempted using the AUTH command. authtype specifies the type of authentication to attempt; it must be one of :login, :plain, and :cram_md5. See the notes on SMTP Authentication in the overview.

Block Usage

When this methods is called with a block, the newly-started SMTP object is yielded to the block, and automatically closed after the block call finishes. Otherwise, it is the caller's responsibility to close the session when finished.

Example

This is very similar to the class method ::start.

require 'net/smtp'
smtp = Net::SMTP.new('smtp.mail.server', 25)
smtp.start(helo_domain, account, password, authtype) do |smtp|
  smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
end

The primary use of this method (as opposed to ::start) is probably to set debugging (set_debug_output) or ESMTP (esmtp=), which must be done before the session is started.

Errors

If session has already been started, an IOError will be raised.

This method may raise:

  • Net::SMTPAuthenticationError

  • Net::SMTPServerBusy

  • Net::SMTPSyntaxError

  • Net::SMTPFatalError

  • Net::SMTPUnknownError

  • Net::OpenTimeout

  • Net::ReadTimeout

  • IOError

# File lib/net/smtp.rb, line 516
def start(helo = 'localhost',
          user = nil, secret = nil, authtype = nil)   # :yield: smtp
  if block_given?
    begin
      do_start helo, user, secret, authtype
      return yield(self)
    ensure
      do_finish
    end
  else
    do_start helo, user, secret, authtype
    return self
  end
end
started?() click to toggle source

true if the SMTP session has been started.

# File lib/net/smtp.rb, line 461
def started?
  @started
end
starttls() click to toggle source

SMTP command dispatcher

# File lib/net/smtp.rb, line 819
def starttls
  getok('STARTTLS')
end
starttls?() click to toggle source

Returns truth value if this object uses STARTTLS. If this object always uses STARTTLS, returns :always. If this object uses STARTTLS when the server support TLS, returns :auto.

# File lib/net/smtp.rb, line 319
def starttls?
  @starttls
end
starttls_always?() click to toggle source

true if this object uses STARTTLS.

# File lib/net/smtp.rb, line 324
def starttls_always?
  @starttls == :always
end
starttls_auto?() click to toggle source

true if this object uses STARTTLS when server advertises STARTTLS.

# File lib/net/smtp.rb, line 329
def starttls_auto?
  @starttls == :auto
end
tls?() click to toggle source

true if this object uses SMTP/TLS (SMTPS).

# File lib/net/smtp.rb, line 289
def tls?
  @tls
end
Also aliased as: ssl?


class Net::SMTP::Response - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::SMTP::Response

This class represents a response received by the SMTP server. Instances of this class are created by the SMTP class; they should not be directly created by the user. For more information on SMTP responses, view Section 4.2 of RFC 5321

In Files

  • lib/net/smtp.rb

Parent

Object

Attributes

status[R]

The three digit reply code of the SMTP response

string[R]

The human readable reply text of the SMTP response

Public Class Methods

new(status, string) click to toggle source

Creates a new instance of the Response class and sets the status and string attributes

# File lib/net/smtp.rb, line 986
def initialize(status, string)
  @status = status
  @string = string
end
parse(str) click to toggle source

Parses the received response and separates the reply code and the human readable reply text

# File lib/net/smtp.rb, line 980
def self.parse(str)
  new(str[0,3], str)
end

Public Instance Methods

capabilities() click to toggle source

Returns a hash of the human readable reply text in the response if it is multiple lines. It does not return the first line. The key of the hash is the first word the value of the hash is an array with each word thereafter being a value in the array

# File lib/net/smtp.rb, line 1029
def capabilities
  return {} unless @string[3, 1] == '-'
  h = {}
  @string.lines.drop(1).each do |line|
    k, *v = line[4..-1].chomp.split
    h[k] = v
  end
  h
end
continue?() click to toggle source

Determines whether the response received was a Positive Intermediate reply (3xx reply code)

# File lib/net/smtp.rb, line 1010
def continue?
  status_type_char() == '3'
end
cram_md5_challenge() click to toggle source

Creates a CRAM-MD5 challenge. You can view more information on CRAM-MD5 on Wikipedia: en.wikipedia.org/wiki/CRAM-MD5

# File lib/net/smtp.rb, line 1021
def cram_md5_challenge
  @string.split(/ /)[1].unpack('m')[0]
end
exception_class() click to toggle source

Determines whether there was an error and raies the appropriate error based on the reply code of the response

# File lib/net/smtp.rb, line 1041
def exception_class
  case @status
  when /\A4/  then SMTPServerBusy
  when /\A50/ then SMTPSyntaxError
  when /\A53/ then SMTPAuthenticationError
  when /\A5/  then SMTPFatalError
  else             SMTPUnknownError
  end
end
message() click to toggle source

The first line of the human readable reply text

# File lib/net/smtp.rb, line 1015
def message
  @string.lines.first
end
status_type_char() click to toggle source

Takes the first digit of the reply code to determine the status type

# File lib/net/smtp.rb, line 998
def status_type_char
  @status[0, 1]
end
success?() click to toggle source

Determines whether the response received was a Positive Completion reply (2xx reply code)

# File lib/net/smtp.rb, line 1004
def success?
  status_type_char() == '2'
end


class Net::SMTPAuthenticationError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::SMTPAuthenticationError

Represents an SMTP authentication error.

In Files

  • lib/net/smtp.rb

Parent

Net::ProtoAuthError

Included Modules

  • Net::SMTPError


module Net::SMTPError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Net::SMTPError

Module mixed in to all SMTP error classes

In Files

  • lib/net/smtp.rb


class Net::SMTPFatalError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::SMTPFatalError

Represents a fatal SMTP error (error code 5xx, except for 500)

In Files

  • lib/net/smtp.rb

Parent

Net::ProtoFatalError

Included Modules

  • Net::SMTPError


class Net::SMTPServerBusy - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::SMTPServerBusy

Represents SMTP error code 420 or 450, a temporary error.

In Files

  • lib/net/smtp.rb

Parent

Net::ProtoServerError

Included Modules

  • Net::SMTPError


class Net::SMTPSyntaxError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::SMTPSyntaxError

Represents an SMTP command syntax error (error code 500)

In Files

  • lib/net/smtp.rb

Parent

Net::ProtoSyntaxError

Included Modules

  • Net::SMTPError


class Net::SMTPUnknownError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::SMTPUnknownError

Unexpected reply code returned from server.

In Files

  • lib/net/smtp.rb

Parent

Net::ProtoUnknownError

Included Modules

  • Net::SMTPError


class Net::SMTPUnsupportedCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::SMTPUnsupportedCommand

Command is not supported on server.

In Files

  • lib/net/smtp.rb

Parent

Net::ProtocolError

Included Modules

  • Net::SMTPError


class Net::Telnet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::Telnet

Net::Telnet

Provides telnet client functionality.

This class also has, through delegation, all the methods of a socket object (by default, a TCPSocket, but can be set by the Proxy option to new()). This provides methods such as close() to end the session and sysread() to read data directly from the host, instead of via the waitfor() mechanism. Note that if you do use sysread() directly when in telnet mode, you should probably pass the output through preprocess() to extract telnet command sequences.

Overview

The telnet protocol allows a client to login remotely to a user account on a server and execute commands via a shell. The equivalent is done by creating a Net::Telnet class with the Host option set to your host, calling login() with your user and password, issuing one or more cmd() calls, and then calling close() to end the session. The waitfor(), print(), puts(), and write() methods, which cmd() is implemented on top of, are only needed if you are doing something more complicated.

A Net::Telnet object can also be used to connect to non-telnet services, such as SMTP or HTTP. In this case, you normally want to provide the Port option to specify the port to connect to, and set the Telnetmode option to false to prevent the client from attempting to interpret telnet command sequences. Generally, login() will not work with other protocols, and you have to handle authentication yourself.

For some protocols, it will be possible to specify the Prompt option once when you create the Telnet object and use cmd() calls; for others, you will have to specify the response sequence to look for as the Match option to every cmd() call, or call puts() and waitfor() directly; for yet others, you will have to use sysread() instead of waitfor() and parse server responses yourself.

It is worth noting that when you create a new Net::Telnet object, you can supply a proxy IO channel via the Proxy option. This can be used to attach the Telnet object to other Telnet objects, to already open sockets, or to any read-write IO object. This can be useful, for instance, for setting up a test fixture for unit testing.

Examples

Log in and send a command, echoing all output to stdout

localhost = Net::Telnet::new("Host" => "localhost",
                             "Timeout" => 10,
                             "Prompt" => /[$%#>] \z/)
localhost.login("username", "password") { |c| print c }
localhost.cmd("command") { |c| print c }
localhost.close

Check a POP server to see if you have mail

pop = Net::Telnet::new("Host" => "your_destination_host_here",
                       "Port" => 110,
                       "Telnetmode" => false,
                       "Prompt" => /^\+OK/)
pop.cmd("user " + "your_username_here") { |c| print c }
pop.cmd("pass " + "your_password_here") { |c| print c }
pop.cmd("list") { |c| print c }

References

There are a large number of RFCs relevant to the Telnet protocol. RFCs 854-861 define the base protocol. For a complete listing of relevant RFCs, see www.omnifarious.org/~hopper/technical/telnet-rfc.html

In Files

  • lib/net/telnet.rb

Parent

Object

Attributes

sock[R]

The socket the Telnet object is using. Note that this object becomes a delegate of the Telnet object, so normally you invoke its methods directly on the Telnet object.

Public Class Methods

new(options) { |mesg| ... } click to toggle source

Creates a new Net::Telnet object.

Attempts to connect to the host (unless the Proxy option is provided: see below). If a block is provided, it is yielded status messages on the attempt to connect to the server, of the form:

Trying localhost...
Connected to localhost.

options is a hash of options. The following example lists all options and their default values.

host = Net::Telnet::new(
         "Host"       => "localhost",  # default: "localhost"
         "Port"       => 23,           # default: 23
         "Binmode"    => false,        # default: false
         "Output_log" => "output_log", # default: nil (no output)
         "Dump_log"   => "dump_log",   # default: nil (no output)
         "Prompt"     => /[$%#>] \z/, # default: /[$%#>] \z/n
         "Telnetmode" => true,         # default: true
         "Timeout"    => 10,           # default: 10
           # if ignore timeout then set "Timeout" to false.
         "Waittime"   => 0,            # default: 0
         "Proxy"      => proxy         # default: nil
                         # proxy is Net::Telnet or IO object
       )

The options have the following meanings:

Host

the hostname or IP address of the host to connect to, as a String. Defaults to “localhost”.

Port

the port to connect to. Defaults to 23.

Binmode

if false (the default), newline substitution is performed. Outgoing LF is converted to CRLF, and incoming CRLF is converted to LF. If true, this substitution is not performed. This value can also be set with the binmode() method. The outgoing conversion only applies to the puts() and print() methods, not the write() method. The precise nature of the newline conversion is also affected by the telnet options SGA and BIN.

Output_log

the name of the file to write connection status messages and all received traffic to. In the case of a proper Telnet session, this will include the client input as echoed by the host; otherwise, it only includes server responses. Output is appended verbatim to this file. By default, no output log is kept.

Dump_log

as for Output_log, except that output is written in hexdump format (16 bytes per line as hex pairs, followed by their printable equivalent), with connection status messages preceded by '#', sent traffic preceded by '>', and received traffic preceded by '<'. By default, not dump log is kept.

Prompt

a regular expression matching the host's command-line prompt sequence. This is needed by the Telnet class to determine when the output from a command has finished and the host is ready to receive a new command. By default, this regular expression is /[$%#>] z/n.

Telnetmode

a boolean value, true by default. In telnet mode, traffic received from the host is parsed for special command sequences, and these sequences are escaped in outgoing traffic sent using puts() or print() (but not write()). If you are using the Net::Telnet object to connect to a non-telnet service (such as SMTP or POP), this should be set to “false” to prevent undesired data corruption. This value can also be set by the telnetmode() method.

Timeout

the number of seconds to wait before timing out both the initial attempt to connect to host (in this constructor), which raises a Net::OpenTimeout, and all attempts to read data from the host, which raises a Net::ReadTimeout (in waitfor(), cmd(), and login()). The default value is 10 seconds. You can disable the timeout by setting this value to false. In this case, the connect attempt will eventually timeout on the underlying connect(2) socket call with an Errno::ETIMEDOUT error (but generally only after a few minutes), but other attempts to read data from the host will hang indefinitely if no data is forthcoming.

Waittime

the amount of time to wait after seeing what looks like a prompt (that is, received data that matches the Prompt option regular expression) to see if more data arrives. If more data does arrive in this time, Net::Telnet assumes that what it saw was not really a prompt. This is to try to avoid false matches, but it can also lead to missing real prompts (if, for instance, a background process writes to the terminal soon after the prompt is displayed). By default, set to 0, meaning not to wait for more data.

Proxy

a proxy object to used instead of opening a direct connection to the host. Must be either another Net::Telnet object or an IO object. If it is another Net::Telnet object, this instance will use that one's socket for communication. If an IO object, it is used directly for communication. Any other kind of object will cause an error to be raised.

# File lib/net/telnet.rb, line 273
def initialize(options) # :yield: mesg
  @options = options
  @options["Host"]       = "localhost"   unless @options.has_key?("Host")
  @options["Port"]       = 23            unless @options.has_key?("Port")
  @options["Prompt"]     = /[$%#>] \z/  unless @options.has_key?("Prompt")
  @options["Timeout"]    = 10            unless @options.has_key?("Timeout")
  @options["Waittime"]   = 0             unless @options.has_key?("Waittime")
  unless @options.has_key?("Binmode")
    @options["Binmode"]    = false
  else
    unless (true == @options["Binmode"] or false == @options["Binmode"])
      raise ArgumentError, "Binmode option must be true or false"
    end
  end

  unless @options.has_key?("Telnetmode")
    @options["Telnetmode"] = true
  else
    unless (true == @options["Telnetmode"] or false == @options["Telnetmode"])
      raise ArgumentError, "Telnetmode option must be true or false"
    end
  end

  @telnet_option = { "SGA" => false, "BINARY" => false }

  if @options.has_key?("Output_log")
    @log = File.open(@options["Output_log"], 'a+')
    @log.sync = true
    @log.binmode
  end

  if @options.has_key?("Dump_log")
    @dumplog = File.open(@options["Dump_log"], 'a+')
    @dumplog.sync = true
    @dumplog.binmode
    def @dumplog.log_dump(dir, x)  # :nodoc:
      len = x.length
      addr = 0
      offset = 0
      while 0 < len
        if len < 16
          line = x[offset, len]
        else
          line = x[offset, 16]
        end
        hexvals = line.unpack('H*')[0]
        hexvals += ' ' * (32 - hexvals.length)
        hexvals = format("%s %s %s %s  " * 4, *hexvals.unpack('a2' * 16))
        line = line.gsub(/[\000-\037\177-\377]/, '.')
        printf "%s 0x%5.5x: %s%s\n", dir, addr, hexvals, line
        addr += 16
        offset += 16
        len -= 16
      end
      print "\n"
    end
  end

  if @options.has_key?("Proxy")
    if @options["Proxy"].kind_of?(Net::Telnet)
      @sock = @options["Proxy"].sock
    elsif @options["Proxy"].kind_of?(IO)
      @sock = @options["Proxy"]
    else
      raise "Error: Proxy must be an instance of Net::Telnet or IO."
    end
  else
    message = "Trying " + @options["Host"] + "...\n"
    yield(message) if block_given?
    @log.write(message) if @options.has_key?("Output_log")
    @dumplog.log_dump('#', message) if @options.has_key?("Dump_log")

    begin
      if @options["Timeout"] == false
        @sock = TCPSocket.open(@options["Host"], @options["Port"])
      else
        Timeout.timeout(@options["Timeout"], Net::OpenTimeout) do
          @sock = TCPSocket.open(@options["Host"], @options["Port"])
        end
      end
    rescue Net::OpenTimeout
      raise Net::OpenTimeout, "timed out while opening a connection to the host"
    rescue
      @log.write($ERROR_INFO.to_s + "\n") if @options.has_key?("Output_log")
      @dumplog.log_dump('#', $ERROR_INFO.to_s + "\n") if @options.has_key?("Dump_log")
      raise
    end
    @sock.sync = true
    @sock.binmode

    message = "Connected to " + @options["Host"] + ".\n"
    yield(message) if block_given?
    @log.write(message) if @options.has_key?("Output_log")
    @dumplog.log_dump('#', message) if @options.has_key?("Dump_log")
  end

end

Public Instance Methods

binmode(mode = nil) click to toggle source

Turn newline conversion on (mode == false) or off (mode == true), or return the current value (mode is not specified).

# File lib/net/telnet.rb, line 405
def binmode(mode = nil)
  case mode
  when nil
    @options["Binmode"]
  when true, false
    @options["Binmode"] = mode
  else
    raise ArgumentError, "argument must be true or false"
  end
end
binmode=(mode) click to toggle source

Turn newline conversion on (false) or off (true).

# File lib/net/telnet.rb, line 417
def binmode=(mode)
  if (true == mode or false == mode)
    @options["Binmode"] = mode
  else
    raise ArgumentError, "argument must be true or false"
  end
end
close() click to toggle source

Closes the connection

# File lib/net/telnet.rb, line 757
def close
  @sock.close
end
cmd(options) { |recvdata| ... } click to toggle source

Send a command to the host.

More exactly, sends a string to the host, and reads in all received data until is sees the prompt or other matched sequence.

If a block is given, the received data will be yielded to it as it is read in. Whether a block is given or not, the received data will be return as a string. Note that the received data includes the prompt and in most cases the host's echo of our command.

options is either a String, specified the string or command to send to the host; or it is a hash of options. If a hash, the following options can be specified:

String

the command or other string to send to the host.

Match

a regular expression, the sequence to look for in the received data before returning. If not specified, the Prompt option value specified when this instance was created will be used, or, failing that, the default prompt of /[$%#>] z/n.

Timeout

the seconds to wait for data from the host before raising a Timeout error. If not specified, the Timeout option value specified when this instance was created will be used, or, failing that, the default value of 10 seconds.

The command or other string will have the newline sequence appended to it.

# File lib/net/telnet.rb, line 678
def cmd(options) # :yield: recvdata
  match    = @options["Prompt"]
  time_out = @options["Timeout"]
  fail_eof = @options["FailEOF"]

  if options.kind_of?(Hash)
    string   = options["String"]
    match    = options["Match"]   if options.has_key?("Match")
    time_out = options["Timeout"] if options.has_key?("Timeout")
    fail_eof = options["FailEOF"] if options.has_key?("FailEOF")
  else
    string = options
  end

  self.puts(string)
  if block_given?
    waitfor({"Prompt" => match, "Timeout" => time_out, "FailEOF" => fail_eof}){|c| yield c }
  else
    waitfor({"Prompt" => match, "Timeout" => time_out, "FailEOF" => fail_eof})
  end
end
login(options, password = nil) { |recvdata| ... } click to toggle source

Login to the host with a given username and password.

The username and password can either be provided as two string arguments in that order, or as a hash with keys “Name” and “Password”.

This method looks for the strings “login” and “Password” from the host to determine when to send the username and password. If the login sequence does not follow this pattern (for instance, you are connecting to a service other than telnet), you will need to handle login yourself.

The password can be omitted, either by only provided one String argument, which will be used as the username, or by providing a has that has no “Password” key. In this case, the method will not look for the “Password:” prompt; if it is sent, it will have to be dealt with by later calls.

The method returns all data received during the login process from the host, including the echoed username but not the password (which the host should not echo). If a block is passed in, this received data is also yielded to the block as it is received.

# File lib/net/telnet.rb, line 722
def login(options, password = nil) # :yield: recvdata
  login_prompt = /[Ll]ogin[: ]*\z/
  password_prompt = /[Pp]ass(?:word|phrase)[: ]*\z/
  if options.kind_of?(Hash)
    username = options["Name"]
    password = options["Password"]
    login_prompt = options["LoginPrompt"] if options["LoginPrompt"]
    password_prompt = options["PasswordPrompt"] if options["PasswordPrompt"]
  else
    username = options
  end

  if block_given?
    line = waitfor(login_prompt){|c| yield c }
    if password
      line += cmd({"String" => username,
                   "Match" => password_prompt}){|c| yield c }
      line += cmd(password){|c| yield c }
    else
      line += cmd(username){|c| yield c }
    end
  else
    line = waitfor(login_prompt)
    if password
      line += cmd({"String" => username,
                   "Match" => password_prompt})
      line += cmd(password)
    else
      line += cmd(username)
    end
  end
  line
end
preprocess(string) click to toggle source

Preprocess received data from the host.

Performs newline conversion and detects telnet command sequences. Called automatically by waitfor(). You should only use this method yourself if you have read input directly using sysread() or similar, and even then only if in telnet mode.

# File lib/net/telnet.rb, line 431
def preprocess(string)
  # combine CR+NULL into CR
  string = string.gsub(/#{CR}#{NULL}/o, CR) if @options["Telnetmode"]

  # combine EOL into "\n"
  string = string.gsub(/#{EOL}/o, "\n") unless @options["Binmode"]

  # remove NULL
  string = string.gsub(/#{NULL}/o, '') unless @options["Binmode"]

  string.gsub(/#{IAC}(
               [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|
               [#{DO}#{DONT}#{WILL}#{WONT}]
                 [#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]|
               #{SB}[^#{IAC}]*#{IAC}#{SE}
             )/no) do
    if    IAC == $1  # handle escaped IAC characters
      IAC
    elsif AYT == $1  # respond to "IAC AYT" (are you there)
      self.write("nobody here but us pigeons" + EOL)
      ''
    elsif DO[0] == $1[0]  # respond to "IAC DO x"
      if OPT_BINARY[0] == $1[1]
        @telnet_option["BINARY"] = true
        self.write(IAC + WILL + OPT_BINARY)
      else
        self.write(IAC + WONT + $1[1..1])
      end
      ''
    elsif DONT[0] == $1[0]  # respond to "IAC DON'T x" with "IAC WON'T x"
      self.write(IAC + WONT + $1[1..1])
      ''
    elsif WILL[0] == $1[0]  # respond to "IAC WILL x"
      if    OPT_BINARY[0] == $1[1]
        self.write(IAC + DO + OPT_BINARY)
      elsif OPT_ECHO[0] == $1[1]
        self.write(IAC + DO + OPT_ECHO)
      elsif OPT_SGA[0]  == $1[1]
        @telnet_option["SGA"] = true
        self.write(IAC + DO + OPT_SGA)
      else
        self.write(IAC + DONT + $1[1..1])
      end
      ''
    elsif WONT[0] == $1[0]  # respond to "IAC WON'T x"
      if    OPT_ECHO[0] == $1[1]
        self.write(IAC + DONT + OPT_ECHO)
      elsif OPT_SGA[0]  == $1[1]
        @telnet_option["SGA"] = false
        self.write(IAC + DONT + OPT_SGA)
      else
        self.write(IAC + DONT + $1[1..1])
      end
      ''
    else
      ''
    end
  end
end
print(string) click to toggle source

Sends a string to the host.

This does not automatically append a newline to the string. Embedded newlines may be converted and telnet command sequences escaped depending upon the values of telnetmode, binmode, and telnet options set by the host.

# File lib/net/telnet.rb, line 625
def print(string)
  string = string.gsub(/#{IAC}/o, IAC + IAC) if @options["Telnetmode"]

  if @options["Binmode"]
    self.write(string)
  else
    if @telnet_option["BINARY"] and @telnet_option["SGA"]
      # IAC WILL SGA IAC DO BIN send EOL --> CR
      self.write(string.gsub(/\n/, CR))
    elsif @telnet_option["SGA"]
      # IAC WILL SGA send EOL --> CR+NULL
      self.write(string.gsub(/\n/, CR + NULL))
    else
      # NONE send EOL --> CR+LF
      self.write(string.gsub(/\n/, EOL))
    end
  end
end
puts(string) click to toggle source

Sends a string to the host.

Same as print(), but appends a newline to the string.

# File lib/net/telnet.rb, line 647
def puts(string)
  self.print(string + "\n")
end
telnetmode(mode = nil) click to toggle source

Set telnet command interpretation on (mode == true) or off (mode == false), or return the current value (mode not provided). It should be on for true telnet sessions, off if using Net::Telnet to connect to a non-telnet service such as SMTP.

# File lib/net/telnet.rb, line 381
def telnetmode(mode = nil)
  case mode
  when nil
    @options["Telnetmode"]
  when true, false
    @options["Telnetmode"] = mode
  else
    raise ArgumentError, "argument must be true or false, or missing"
  end
end
telnetmode=(mode) click to toggle source

Turn telnet command interpretation on (true) or off (false). It should be on for true telnet sessions, off if using Net::Telnet to connect to a non-telnet service such as SMTP.

# File lib/net/telnet.rb, line 395
def telnetmode=(mode)
  if (true == mode or false == mode)
    @options["Telnetmode"] = mode
  else
    raise ArgumentError, "argument must be true or false"
  end
end
waitfor(options) { |recvdata| ... } click to toggle source

Read data from the host until a certain sequence is matched.

If a block is given, the received data will be yielded as it is read in (not necessarily all in one go), or nil if EOF occurs before any data is received. Whether a block is given or not, all data read will be returned in a single string, or again nil if EOF occurs before any data is received. Note that received data includes the matched sequence we were looking for.

options can be either a regular expression or a hash of options. If a regular expression, this specifies the data to wait for. If a hash, this can specify the following options:

Match

a regular expression, specifying the data to wait for.

Prompt

as for Match; used only if Match is not specified.

String

as for Match, except a string that will be converted into a regular expression. Used only if Match and Prompt are not specified.

Timeout

the number of seconds to wait for data from the host before raising a Timeout::Error. If set to false, no timeout will occur. If not specified, the Timeout option value specified when this instance was created will be used, or, failing that, the default value of 10 seconds.

Waittime

the number of seconds to wait after matching against the input data to see if more data arrives. If more data arrives within this time, we will judge ourselves not to have matched successfully, and will continue trying to match. If not specified, the Waittime option value specified when this instance was created will be used, or, failing that, the default value of 0 seconds, which means not to wait for more input.

FailEOF

if true, when the remote end closes the connection then an EOFError will be raised. Otherwise, defaults to the old behaviour that the function will return whatever data has been received already, or nil if nothing was received.

# File lib/net/telnet.rb, line 528
def waitfor(options) # :yield: recvdata
  time_out = @options["Timeout"]
  waittime = @options["Waittime"]
  fail_eof = @options["FailEOF"]

  if options.kind_of?(Hash)
    prompt   = if options.has_key?("Match")
                 options["Match"]
               elsif options.has_key?("Prompt")
                 options["Prompt"]
               elsif options.has_key?("String")
                 Regexp.new( Regexp.quote(options["String"]) )
               end
    time_out = options["Timeout"]  if options.has_key?("Timeout")
    waittime = options["Waittime"] if options.has_key?("Waittime")
    fail_eof = options["FailEOF"]  if options.has_key?("FailEOF")
  else
    prompt = options
  end

  if time_out == false
    time_out = nil
  end

  line = ''
  buf = ''
  rest = ''
  until(prompt === line and not IO::select([@sock], nil, nil, waittime))
    unless IO::select([@sock], nil, nil, time_out)
      raise Net::ReadTimeout, "timed out while waiting for more data"
    end
    begin
      c = @sock.readpartial(1024 * 1024)
      @dumplog.log_dump('<', c) if @options.has_key?("Dump_log")
      if @options["Telnetmode"]
        c = rest + c
        if Integer(c.rindex(/#{IAC}#{SE}/o) || 0) <
           Integer(c.rindex(/#{IAC}#{SB}/o) || 0)
          buf = preprocess(c[0 ... c.rindex(/#{IAC}#{SB}/o)])
          rest = c[c.rindex(/#{IAC}#{SB}/o) .. -1]
        elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/o) ||
                   c.rindex(/\r\z/o)
          buf = preprocess(c[0 ... pt])
          rest = c[pt .. -1]
        else
          buf = preprocess(c)
          rest = ''
        end
     else
       # Not Telnetmode.
       #
       # We cannot use preprocess() on this data, because that
       # method makes some Telnetmode-specific assumptions.
       buf = rest + c
       rest = ''
       unless @options["Binmode"]
         if pt = buf.rindex(/\r\z/o)
           buf = buf[0 ... pt]
           rest = buf[pt .. -1]
         end
         buf.gsub!(/#{EOL}/o, "\n")
       end
      end
      @log.print(buf) if @options.has_key?("Output_log")
      line += buf
      yield buf if block_given?
    rescue EOFError # End of file reached
      raise if fail_eof
      if line == ''
        line = nil
        yield nil if block_given?
      end
      break
    end
  end
  line
end
write(string) click to toggle source

Write string to the host.

Does not perform any conversions on string. Will log string to the dumplog, if the Dump_log option is set.

# File lib/net/telnet.rb, line 610
def write(string)
  length = string.length
  while 0 < length
    IO::select(nil, [@sock])
    @dumplog.log_dump('>', string[-length..-1]) if @options.has_key?("Dump_log")
    length -= @sock.syswrite(string[-length..-1])
  end
end


class Net::WriteAdapter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Net::WriteAdapter

The writer adapter class

In Files

  • lib/net/protocol.rb

Parent

Object

Public Class Methods

new(socket, method) click to toggle source
# File lib/net/protocol.rb, line 362
def initialize(socket, method)
  @socket = socket
  @method_id = method
end

Public Instance Methods

<<(str) click to toggle source
# File lib/net/protocol.rb, line 377
def <<(str)
  write str
  self
end
inspect() click to toggle source
# File lib/net/protocol.rb, line 367
def inspect
  "#<#{self.class} socket=#{@socket.inspect}>"
end
print(str) click to toggle source
Alias for: write
printf(*args) click to toggle source
# File lib/net/protocol.rb, line 386
def printf(*args)
  write sprintf(*args)
end
puts(str = '') click to toggle source
# File lib/net/protocol.rb, line 382
def puts(str = '')
  write str.chomp("\n") + "\n"
end
write(str) click to toggle source
# File lib/net/protocol.rb, line 371
def write(str)
  @socket.__send__(@method_id, str)
end
Also aliased as: print


module Newton - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Newton

newton.rb

Solves the nonlinear algebraic equation system f = 0 by Newton's method. This program is not dependent on BigDecimal.

To call:

  n = nlsolve(f,x)
where n is the number of iterations required,
      x is the initial value vector
      f is an Object which is used to compute the values of the equations to be solved.

It must provide the following methods:

f.values(x)

returns the values of all functions at x

f.zero

returns 0.0

f.one

returns 1.0

f.two

returns 2.0

f.ten

returns 10.0

f.eps

returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.

On exit, x is the solution vector.

In Files

  • ext/bigdecimal/lib/bigdecimal/newton.rb

Included Modules

  • LUSolve
  • Jacobian

Public Instance Methods

nlsolve(f,x) click to toggle source
# File ext/bigdecimal/lib/bigdecimal/newton.rb, line 42
def nlsolve(f,x)
  nRetry = 0
  n = x.size

  f0 = f.values(x)
  zero = f.zero
  one  = f.one
  two  = f.two
  p5 = one/two
  d  = norm(f0,zero)
  minfact = f.ten*f.ten*f.ten
  minfact = one/minfact
  e = f.eps
  while d >= e do
    nRetry += 1
    # Not yet converged. => Compute Jacobian matrix
    dfdx = jacobian(f,f0,x)
    # Solve dfdx*dx = -f0 to estimate dx
    dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero)
    fact = two
    xs = x.dup
    begin
      fact *= p5
      if fact < minfact then
        raise "Failed to reduce function values."
      end
      for i in 0...n do
        x[i] = xs[i] - dx[i]*fact
      end
      f0 = f.values(x)
      dn = norm(f0,zero)
    end while(dn>=d)
    d = dn
  end
  nRetry
end
norm(fv,zero=0.0) click to toggle source
# File ext/bigdecimal/lib/bigdecimal/newton.rb, line 33
def norm(fv,zero=0.0)
  s = zero
  n = fv.size
  for i in 0...n do
    s += fv[i]*fv[i]
  end
  s
end


class Numeric - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Numeric

mathn

mathn is a library for changing the way Ruby does math. If you need more precise rounding with multiple division or exponentiation operations, then mathn is the right tool.

Without mathn:

3 / 2 => 1 # Integer

With mathn:

3 / 2 => 3/2 # Rational

mathn features late rounding and lacks truncation of intermediate results:

Without mathn:

20 / 9 * 3 * 14 / 7 * 3 / 2 # => 18

With mathn:

20 / 9 * 3 * 14 / 7 * 3 / 2 # => 20

When you require 'mathn', the libraries for Prime, CMath, Matrix and Vector are also loaded.

Copyright

Author: Keiju ISHITSUKA (SHL Japan Inc.)

In Files

  • lib/mathn.rb

Parent

Object


class OLEProperty - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OLEProperty

OLEProperty helper class of Property with arguments.

In Files

  • ext/win32ole/lib/win32ole/property.rb

Parent

Object

Public Class Methods

new(obj, dispid, gettypes, settypes) click to toggle source
# File ext/win32ole/lib/win32ole/property.rb, line 4
def initialize(obj, dispid, gettypes, settypes)
  @obj = obj
  @dispid = dispid
  @gettypes = gettypes
  @settypes = settypes
end

Public Instance Methods

[](*args) click to toggle source
# File ext/win32ole/lib/win32ole/property.rb, line 10
def [](*args)
  @obj._getproperty(@dispid, args, @gettypes)
end
[]=(*args) click to toggle source
# File ext/win32ole/lib/win32ole/property.rb, line 13
def []=(*args)
  @obj._setproperty(@dispid, args, @settypes)
end


class Object - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Object

In Files

  • lib/benchmark.rb
  • lib/complex.rb
  • lib/csv.rb
  • lib/debug.rb
  • lib/delegate.rb
  • lib/drb/drb.rb
  • lib/English.rb
  • lib/irb/ext/use-loader.rb
  • lib/irb/src_encoding.rb
  • lib/irb/xmp.rb
  • lib/mathn.rb
  • lib/minitest/mock.rb
  • lib/minitest/spec.rb
  • lib/minitest/unit.rb
  • lib/mkmf.rb
  • lib/net/http/backward.rb
  • lib/net/http/responses.rb
  • lib/net/imap.rb
  • lib/optparse.rb
  • lib/pp.rb
  • lib/racc/parser.rb
  • lib/rake/classic_namespace.rb
  • lib/rake/clean.rb
  • lib/rake/contrib/publisher.rb
  • lib/rake/dsl_definition.rb
  • lib/rake.rb
  • lib/rexml/xpath_parser.rb
  • lib/rubygems/syck_hack.rb
  • lib/sync.rb
  • lib/thwait.rb
  • lib/timeout.rb
  • lib/tracer.rb
  • lib/un.rb
  • lib/webrick/httpservlet/cgi_runner.rb
  • lib/yaml.rb
  • ext/digest/lib/digest.rb
  • ext/psych/lib/psych/core_ext.rb
  • ext/psych/lib/psych/deprecated.rb
  • ext/psych/lib/psych/visitors/to_ruby.rb
  • ext/ripper/ripper.c

Parent

BasicObject

Included Modules

  • Benchmark
  • MakeMakefile
  • PP::ObjectMixin

Constants

NOENCODING
ParseError
Synchronizer

An alias for Sync from sync.rb. See Sync_m for details.

Synchronizer_m

An alias for Sync_m from sync.rb

ThWait

An alias for ThreadsWait from thwait.rb

TimeoutError

Another name for Timeout::Error, defined for backwards compatibility with earlier versions of timeout.rb.

Version
YAML

Public Class Methods

yaml_tag(url) click to toggle source
# File ext/psych/lib/psych/core_ext.rb, line 2
def self.yaml_tag url
  Psych.add_tag(url, self)
end

Public Instance Methods

CSV(*args, &block) click to toggle source

Passes args to CSV.instance.

CSV("CSV,data").read
  #=> [["CSV", "data"]]

If a block is given, the instance is passed the block and the return value becomes the return value of the block.

CSV("CSV,data") { |c|
  c.read.any? { |a| a.include?("data") }
} #=> true

CSV("CSV,data") { |c|
  c.read.any? { |a| a.include?("zombies") }
} #=> false

# File lib/csv.rb, line 2294
def CSV(*args, &block)
  CSV.instance(*args, &block)
end
DelegateClass(superclass) click to toggle source

The primary interface to this library. Use to setup delegation when defining your class.

class MyClass < DelegateClass(ClassToDelegateTo) # Step 1
  def initialize
    super(obj_of_ClassToDelegateTo)              # Step 2
  end
end

Here's a sample of use from Tempfile which is really a File object with a few special rules about storage location and when the File should be deleted. That makes for an almost textbook perfect example of how to use delegation.

class Tempfile < DelegateClass(File)
  # constant and class member data initialization...

  def initialize(basename, tmpdir=Dir::tmpdir)
    # build up file path/name in var tmpname...

    @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)

    # ...

    super(@tmpfile)

    # below this point, all methods of File are supported...
  end

  # ...
end

# File lib/delegate.rb, line 335
def DelegateClass(superclass)
  klass = Class.new(Delegator)
  methods = superclass.instance_methods
  methods -= ::Delegator.public_api
  methods -= [:to_s,:inspect,:=~,:!~,:===]
  klass.module_eval do
    def __getobj__  # :nodoc:
      @delegate_dc_obj
    end
    def __setobj__(obj)  # :nodoc:
      raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
      @delegate_dc_obj = obj
    end
    methods.each do |method|
      define_method(method, Delegator.delegating_block(method))
    end
  end
  klass.define_singleton_method :public_instance_methods do |all=true|
    super(all) - superclass.protected_instance_methods
  end
  klass.define_singleton_method :protected_instance_methods do |all=true|
    super(all) | superclass.protected_instance_methods
  end
  return klass
end
Digest(name) → digest_subclass click to toggle source

Returns a Digest subclass by name.

require 'digest'

Digest("MD5")
# => Digest::MD5

Digest("Foo")
# => LoadError: library not found for class Digest::Foo -- digest/foo

# File ext/digest/lib/digest.rb, line 86
def Digest(name)
  Digest.const_get(name)
end
chmod() click to toggle source

Change the mode of each FILE to OCTAL-MODE.

ruby -run -e chmod -- [OPTION] OCTAL-MODE FILE

-v          verbose
# File lib/un.rb, line 206
def chmod
  setup do |argv, options|
    mode = argv.shift.oct
    FileUtils.chmod mode, argv, options
  end
end
cp() click to toggle source

Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY

ruby -run -e cp -- [OPTION] SOURCE DEST

-p          preserve file attributes if possible
-r          copy recursively
-v          verbose
# File lib/un.rb, line 77
def cp
  setup("pr") do |argv, options|
    cmd = "cp"
    cmd += "_r" if options.delete :r
    options[:preserve] = true if options.delete :p
    dest = argv.pop
    argv = argv[0] if argv.size == 1
    FileUtils.send cmd, argv, dest, options
  end
end
dclone() click to toggle source

provides a unified clone operation, for REXML::XPathParser to use across multiple Object types

# File lib/rexml/xpath_parser.rb, line 10
def dclone
  clone
end
default_src_encoding() click to toggle source

DO NOT WRITE ANY MAGIC COMMENT HERE.

# File lib/irb/src_encoding.rb, line 2
def default_src_encoding
  return __ENCODING__
end
help() click to toggle source

Display help message.

ruby -run -e help [COMMAND]
# File lib/un.rb, line 336
def help
  setup do |argv,|
    all = argv.empty?
    open(__FILE__) do |me|
      while me.gets("##\n")
        if help = me.gets("\n\n")
          if all or argv.delete help[/-e \w+/].sub(/-e /, "")
            print help.gsub(/^# ?/, "")
          end
        end
      end
    end
  end
end
httpd() click to toggle source

Run WEBrick HTTP server.

ruby -run -e httpd -- [OPTION] DocumentRoot

--bind-address=ADDR         address to bind
--port=NUM                  listening port number
--max-clients=MAX           max number of simultaneous clients
--temp-dir=DIR              temporary directory
--do-not-reverse-lookup     disable reverse lookup
--request-timeout=SECOND    request timeout in seconds
--http-version=VERSION      HTTP version
-v                          verbose
# File lib/un.rb, line 305
def httpd
  setup("", "BindAddress=ADDR", "Port=PORT", "MaxClients=NUM", "TempDir=DIR",
        "DoNotReverseLookup", "RequestTimeout=SECOND", "HTTPVersion=VERSION") do
    |argv, options|
    require 'webrick'
    opt = options[:RequestTimeout] and options[:RequestTimeout] = opt.to_i
    [:Port, :MaxClients].each do |name|
      opt = options[name] and (options[name] = Integer(opt)) rescue nil
    end
    unless argv.size == 1
      raise ArgumentError, "DocumentRoot is mandatory"
    end
    options[:DocumentRoot] = argv.shift
    s = WEBrick::HTTPServer.new(options)
    shut = proc {s.shutdown}
    siglist = %wTERM QUIT"
    siglist.concat(%wHUP INT") if STDIN.tty?
    siglist &= Signal.list.keys
    siglist.each do |sig|
      Signal.trap(sig, shut)
    end
    s.start
  end
end
install() click to toggle source

Copy SOURCE to DEST.

ruby -run -e install -- [OPTION] SOURCE DEST

-p          apply access/modification times of SOURCE files to
            corresponding destination files
-m          set permission mode (as in chmod), instead of 0755
-v          verbose
# File lib/un.rb, line 188
def install
  setup("pm:") do |argv, options|
    options[:mode] = (mode = options.delete :m) ? mode.oct : 0755
    options[:preserve] = true if options.delete :p
    dest = argv.pop
    argv = argv[0] if argv.size == 1
    FileUtils.install argv, dest, options
  end
end
ln() click to toggle source

Create a link to the specified TARGET with LINK_NAME.

ruby -run -e ln -- [OPTION] TARGET LINK_NAME

-s          make symbolic links instead of hard links
-f          remove existing destination files
-v          verbose
# File lib/un.rb, line 98
def ln
  setup("sf") do |argv, options|
    cmd = "ln"
    cmd += "_s" if options.delete :s
    options[:force] = true if options.delete :f
    dest = argv.pop
    argv = argv[0] if argv.size == 1
    FileUtils.send cmd, argv, dest, options
  end
end
mkdir() click to toggle source

Create the DIR, if they do not already exist.

ruby -run -e mkdir -- [OPTION] DIR

-p          no error if existing, make parent directories as needed
-v          verbose
# File lib/un.rb, line 153
def mkdir
  setup("p") do |argv, options|
    cmd = "mkdir"
    cmd += "_p" if options.delete :p
    FileUtils.send cmd, argv, options
  end
end
mkmf() click to toggle source

Create makefile using mkmf.

ruby -run -e mkmf -- [OPTION] EXTNAME [OPTION]

-d ARGS     run dir_config
-h ARGS     run have_header
-l ARGS     run have_library
-f ARGS     run have_func
-v ARGS     run have_var
-t ARGS     run have_type
-m ARGS     run have_macro
-c ARGS     run have_const
--vendor    install to vendor_ruby
# File lib/un.rb, line 274
def mkmf
  setup("d:h:l:f:v:t:m:c:", "vendor") do |argv, options|
    require 'mkmf'
    opt = options[:d] and opt.split(/:/).each {|n| dir_config(*n.split(/,/))}
    opt = options[:h] and opt.split(/:/).each {|n| have_header(*n.split(/,/))}
    opt = options[:l] and opt.split(/:/).each {|n| have_library(*n.split(/,/))}
    opt = options[:f] and opt.split(/:/).each {|n| have_func(*n.split(/,/))}
    opt = options[:v] and opt.split(/:/).each {|n| have_var(*n.split(/,/))}
    opt = options[:t] and opt.split(/:/).each {|n| have_type(*n.split(/,/))}
    opt = options[:m] and opt.split(/:/).each {|n| have_macro(*n.split(/,/))}
    opt = options[:c] and opt.split(/:/).each {|n| have_const(*n.split(/,/))}
    $configure_args["--vendor"] = true if options[:vendor]
    create_makefile(*argv)
  end
end
mv() click to toggle source

Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.

ruby -run -e mv -- [OPTION] SOURCE DEST

-v          verbose
# File lib/un.rb, line 117
def mv
  setup do |argv, options|
    dest = argv.pop
    argv = argv[0] if argv.size == 1
    FileUtils.mv argv, dest, options
  end
end
pretty_print(q) click to toggle source
# File lib/pp.rb, line 512
def pretty_print(q)
  q.text inspect
end
pretty_print_cycle(q) click to toggle source
# File lib/pp.rb, line 504
def pretty_print_cycle(q)
  q.text inspect
end
to_yaml(options = {}) click to toggle source

Convert an object to YAML. See Psych.dump for more information on the available options.

# File ext/psych/lib/psych/core_ext.rb, line 13
def psych_to_yaml options = {}
  Psych.dump self, options
end
Also aliased as: to_yaml
rm() click to toggle source

Remove the FILE

ruby -run -e rm -- [OPTION] FILE

-f          ignore nonexistent files
-r          remove the contents of directories recursively
-v          verbose
# File lib/un.rb, line 135
def rm
  setup("fr") do |argv, options|
    cmd = "rm"
    cmd += "_r" if options.delete :r
    options[:force] = true if options.delete :f
    FileUtils.send cmd, argv, options
  end
end
rmdir() click to toggle source

Remove the DIR.

ruby -run -e rmdir -- [OPTION] DIR

-p          remove DIRECTORY and its ancestors.
-v          verbose
# File lib/un.rb, line 170
def rmdir
  setup("p") do |argv, options|
    options[:parents] = true if options.delete :p
    FileUtils.rmdir argv, options
  end
end
setup(options = "", *long_options) { |argv, opt_hash| ... } click to toggle source
# File lib/un.rb, line 35
def setup(options = "", *long_options)
  opt_hash = {}
  argv = []
  OptionParser.new do |o|
    options.scan(/.:?/) do |s|
      opt_name = s.delete(":").intern
      o.on("-" + s.tr(":", " ")) do |val|
        opt_hash[opt_name] = val
      end
    end
    long_options.each do |s|
      opt_name, arg_name = s.split(/(?=[\s=])/, 2)
      opt_name.sub!(/\A--/, '')
      s = "--#{opt_name.gsub(/([A-Z]+|[a-z])([A-Z])/, '\1-\2').downcase}#{arg_name}"
      puts "#{opt_name}=>#{s}" if $DEBUG
      opt_name = opt_name.intern
      o.on(s) do |val|
        opt_hash[opt_name] = val
      end
    end
    o.on("-v") do opt_hash[:verbose] = true end
    o.order!(ARGV) do |x|
      if /[*?\[{]/ =~ x
        argv.concat(Dir[x])
      else
        argv << x
      end
    end
  end
  yield argv, opt_hash
end
sysread(io, size) click to toggle source

cgi_runner.rb – CGI launcher.

Author: IPR – Internet Programming with Ruby – writers Copyright © 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU Copyright © 2002 Internet Programming with Ruby writers. All rights reserved.

$IPR: cgi_runner.rb,v 1.9 2002/09/25 11:33:15 gotoyuzo Exp $

# File lib/webrick/httpservlet/cgi_runner.rb, line 11
def sysread(io, size)
  buf = ""
  while size > 0
    tmp = io.sysread(size)
    buf << tmp
    size -= tmp.bytesize
  end
  return buf
end
timeout(n, e = nil, &block) click to toggle source

Identical to:

Timeout::timeout(n, e, &block).

This method is deprecated and provided only for backwards compatibility. You should use Timeout#timeout instead.

# File lib/timeout.rb, line 96
def timeout(n, e = nil, &block)
  Timeout::timeout(n, e, &block)
end
to_yaml(options = {}) click to toggle source
Alias for: psych_to_yaml
touch() click to toggle source

Update the access and modification times of each FILE to the current time.

ruby -run -e touch -- [OPTION] FILE

-v          verbose
# File lib/un.rb, line 221
def touch
  setup do |argv, options|
    FileUtils.touch argv, options
  end
end
wait_writable() click to toggle source

Wait until the file becomes writable.

ruby -run -e wait_writable -- [OPTION] FILE

-n RETRY    count to retry
-w SEC      each wait time in seconds
-v          verbose
# File lib/un.rb, line 237
def wait_writable
  setup("n:w:v") do |argv, options|
    verbose = options[:verbose]
    n = options[:n] and n = Integer(n)
    wait = (wait = options[:w]) ? Float(wait) : 0.2
    argv.each do |file|
      begin
        open(file, "r+b")
      rescue Errno::ENOENT
        break
      rescue Errno::EACCES => e
        raise if n and (n -= 1) <= 0
        puts e
        STDOUT.flush
        sleep wait
        retry
      end
    end
  end
end
xmp(exps, bind = nil) click to toggle source

A convenience method that's only available when the you require the IRB::XMP standard library.

Creates a new XMP object, using the given expressions as the exps parameter, and optional binding as bind or uses the top-level binding. Then evaluates the given expressions using the :XMP prompt mode.

For example:

require 'irb/xmp'
ctx = binding
xmp 'foo = "bar"', ctx
#=> foo = "bar"
  #==>"bar"
ctx.eval 'foo'
#=> "bar"

See XMP.new for more information.

# File lib/irb/xmp.rb, line 168
def xmp(exps, bind = nil)
  bind = IRB::Frame.top(1) unless bind
  xmp = XMP.new(bind)
  xmp.puts exps
  xmp
end


class Racc::ParseError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Racc::ParseError

In Files

  • lib/racc/parser.rb

Parent

StandardError


class Sync - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Sync

A class that providesa two-phase lock with a counter. See Sync_m for details.

In Files

  • lib/sync.rb

Parent

Object

Included Modules

  • Sync_m


module Sync_m - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Sync_m

A module that provides a two-phase lock with a counter.

In Files

  • lib/sync.rb

Constants

EX
SH
UN

lock mode

Attributes

sync_ex_count[RW]
sync_ex_locker[RW]
sync_mode[RW]
sync_sh_locker[RW]
sync_upgrade_waiting[RW]
sync_waiting[RW]

Public Class Methods

append_features(cl) click to toggle source
# File lib/sync.rb, line 89
def Sync_m.append_features(cl)
  super
  # do nothing for Modules
  # make aliases for Classes.
  define_aliases(cl) unless cl.instance_of?(Module)
  self
end
define_aliases(cl) click to toggle source
# File lib/sync.rb, line 77
def Sync_m.define_aliases(cl)
  cl.module_eval %q{
    alias locked? sync_locked?
    alias shared? sync_shared?
    alias exclusive? sync_exclusive?
    alias lock sync_lock
    alias unlock sync_unlock
    alias try_lock sync_try_lock
    alias synchronize sync_synchronize
  }
end
extend_object(obj) click to toggle source
# File lib/sync.rb, line 97
def Sync_m.extend_object(obj)
  super
  obj.sync_extend
end
new(*args) click to toggle source
# File lib/sync.rb, line 266
def initialize(*args)
  super
  sync_initialize
end

Public Instance Methods

sync_exclusive?() click to toggle source
# File lib/sync.rb, line 124
def sync_exclusive?
  sync_mode == EX
end
sync_extend() click to toggle source
# File lib/sync.rb, line 102
def sync_extend
  unless (defined? locked? and
          defined? shared? and
          defined? exclusive? and
          defined? lock and
          defined? unlock and
          defined? try_lock and
          defined? synchronize)
    Sync_m.define_aliases(singleton_class)
  end
  sync_initialize
end
sync_inspect() click to toggle source
# File lib/sync.rb, line 248
def sync_inspect
  sync_iv = instance_variables.select{|iv| /^@sync_/ =~ iv.id2name}.collect{|iv| iv.id2name + '=' + instance_eval(iv.id2name).inspect}.join(",")
  print "<#{self.class}.extend Sync_m: #{inspect}, <Sync_m: #{sync_iv}>"
end
sync_lock(m = EX) click to toggle source
# File lib/sync.rb, line 136
def sync_lock(m = EX)
  return unlock if m == UN
  Thread.handle_interrupt(StandardError => :on_blocking) do
    while true
      @sync_mutex.synchronize do
        begin
          if sync_try_lock_sub(m)
            return self
          else
            if sync_sh_locker[Thread.current]
              sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
              sync_sh_locker.delete(Thread.current)
            else
              unless sync_waiting.include?(Thread.current) || sync_upgrade_waiting.reverse_each.any?{|w| w.first == Thread.current }
                sync_waiting.push Thread.current
              end
            end
            @sync_mutex.sleep
          end
        ensure
          sync_waiting.delete(Thread.current)
        end
      end
    end
  end
  self
end
sync_locked?() click to toggle source

accessing

# File lib/sync.rb, line 116
def sync_locked?
  sync_mode != UN
end
sync_shared?() click to toggle source
# File lib/sync.rb, line 120
def sync_shared?
  sync_mode == SH
end
sync_synchronize(mode = EX) { || ... } click to toggle source
# File lib/sync.rb, line 229
def sync_synchronize(mode = EX)
  Thread.handle_interrupt(StandardError => :on_blocking) do
    sync_lock(mode)
    begin
      yield
    ensure
      sync_unlock
    end
  end
end
sync_try_lock(mode = EX) click to toggle source

locking methods.

# File lib/sync.rb, line 129
def sync_try_lock(mode = EX)
  return unlock if mode == UN
  @sync_mutex.synchronize do
    sync_try_lock_sub(mode)
  end
end
sync_unlock(m = EX) click to toggle source
# File lib/sync.rb, line 164
def sync_unlock(m = EX)
  wakeup_threads = []
  @sync_mutex.synchronize do
    if sync_mode == UN
      Err::UnknownLocker.Fail(Thread.current)
    end

    m = sync_mode if m == EX and sync_mode == SH

    runnable = false
    case m
    when UN
      Err::UnknownLocker.Fail(Thread.current)

    when EX
      if sync_ex_locker == Thread.current
        if (self.sync_ex_count = sync_ex_count - 1) == 0
          self.sync_ex_locker = nil
          if sync_sh_locker.include?(Thread.current)
            self.sync_mode = SH
          else
            self.sync_mode = UN
          end
          runnable = true
        end
      else
        Err::UnknownLocker.Fail(Thread.current)
      end

    when SH
      if (count = sync_sh_locker[Thread.current]).nil?
        Err::UnknownLocker.Fail(Thread.current)
      else
        if (sync_sh_locker[Thread.current] = count - 1) == 0
          sync_sh_locker.delete(Thread.current)
          if sync_sh_locker.empty? and sync_ex_count == 0
            self.sync_mode = UN
            runnable = true
          end
        end
      end
    end

    if runnable
      if sync_upgrade_waiting.size > 0
        th, count = sync_upgrade_waiting.shift
        sync_sh_locker[th] = count
        th.wakeup
        wakeup_threads.push th
      else
        wait = sync_waiting
        self.sync_waiting = []
        for th in wait
          th.wakeup
          wakeup_threads.push th
        end
      end
    end
  end
  for th in wakeup_threads
    th.run
  end
  self
end


class ThreadsWait - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class ThreadsWait

This class watches for termination of multiple threads. Basic functionality (wait until specified threads have terminated) can be accessed through the class method ::all_waits. Finer control can be gained using instance methods.

Example:

ThreadsWait.all_wait(thr1, thr2, ...) do |t|
  STDERR.puts "Thread #{t} has terminated."
end

th = ThreadsWait.new(thread1,...)
th.next_wait # next one to be done

In Files

  • lib/thwait.rb

Parent

Object

Constants

RCS_ID

Attributes

threads[R]

Returns the array of threads that have not terminated yet.

Public Class Methods

all_waits(*threads) { |thread| ... } click to toggle source

Waits until all specified threads have terminated. If a block is provided, it is executed for each thread as they terminate.

# File lib/thwait.rb, line 38
def ThreadsWait.all_waits(*threads) # :yield: thread
  tw = ThreadsWait.new(*threads)
  if block_given?
    tw.all_waits do |th|
      yield th
    end
  else
    tw.all_waits
  end
end
new(*threads) click to toggle source

Creates a ThreadsWait object, specifying the threads to wait on. Non-blocking.

# File lib/thwait.rb, line 53
def initialize(*threads)
  @threads = []
  @wait_queue = Queue.new
  join_nowait(*threads) unless threads.empty?
end

Public Instance Methods

all_waits() { |th| ... } click to toggle source

Waits until all of the specified threads are terminated. If a block is supplied for the method, it is executed for each thread termination.

Raises exceptions in the same manner as next_wait.

# File lib/thwait.rb, line 126
def all_waits
  until @threads.empty?
    th = next_wait
    yield th if block_given?
  end
end
empty?() click to toggle source

Returns true if there are no threads in the pool still running.

# File lib/thwait.rb, line 65
def empty?
  @threads.empty?
end
finished?() click to toggle source

Returns true if any thread has terminated and is ready to be collected.

# File lib/thwait.rb, line 72
def finished?
  !@wait_queue.empty?
end
join(*threads) click to toggle source

Waits for specified threads to terminate, and returns when one of the threads terminated.

# File lib/thwait.rb, line 80
def join(*threads)
  join_nowait(*threads)
  next_wait
end
join_nowait(*threads) click to toggle source

Specifies the threads that this object will wait for, but does not actually wait.

# File lib/thwait.rb, line 89
def join_nowait(*threads)
  threads.flatten!
  @threads.concat threads
  for th in threads
    Thread.start(th) do |t|
      begin
        t.join
      ensure
        @wait_queue.push t
      end
    end
  end
end
next_wait(nonblock = nil) click to toggle source

Waits until any of the specified threads has terminated, and returns the one that does.

If there is no thread to wait, raises ErrNoWaitingThread. If nonblock is true, and there is no terminated thread, raises ErrNoFinishedThread.

# File lib/thwait.rb, line 110
def next_wait(nonblock = nil)
  ThreadsWait.fail ErrNoWaitingThread if @threads.empty?
  begin
    @threads.delete(th = @wait_queue.pop(nonblock))
    th
  rescue ThreadError
    ThreadsWait.fail ErrNoFinishedThread
  end
end


class Timeout::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Timeout::Error

Raised by Timeout#timeout when the block times out.

In Files

  • lib/timeout.rb

Parent

RuntimeError


module Observable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Observable

The Observer pattern (also known as publish/subscribe) provides a simple mechanism for one object to inform a set of interested third-party objects when its state changes.

Mechanism

The notifying class mixes in the Observable module, which provides the methods for managing the associated observer objects.

The observers must implement a method called update to receive notifications.

The observable object must:

  • assert that it has #changed

  • call #notify_observers

Example

The following example demonstrates this nicely. A Ticker, when run, continually receives the stock Price for its @symbol. A Warner is a general observer of the price, and two warners are demonstrated, a WarnLow and a WarnHigh, which print a warning if the price is below or above their set limits, respectively.

The update callback allows the warners to run without being explicitly called. The system is set up with the Ticker and several observers, and the observers do their duty without the top-level code having to interfere.

Note that the contract between publisher and subscriber (observable and observer) is not declared or enforced. The Ticker publishes a time and a price, and the warners receive that. But if you don't ensure that your contracts are correct, nothing else can warn you.

require "observer"

class Ticker          ### Periodically fetch a stock price.
  include Observable

  def initialize(symbol)
    @symbol = symbol
  end

  def run
    lastPrice = nil
    loop do
      price = Price.fetch(@symbol)
      print "Current price: #{price}\n"
      if price != lastPrice
        changed                 # notify observers
        lastPrice = price
        notify_observers(Time.now, price)
      end
      sleep 1
    end
  end
end

class Price           ### A mock class to fetch a stock price (60 - 140).
  def Price.fetch(symbol)
    60 + rand(80)
  end
end

class Warner          ### An abstract observer of Ticker objects.
  def initialize(ticker, limit)
    @limit = limit
    ticker.add_observer(self)
  end
end

class WarnLow < Warner
  def update(time, price)       # callback for observer
    if price < @limit
      print "--- #{time.to_s}: Price below #@limit: #{price}\n"
    end
  end
end

class WarnHigh < Warner
  def update(time, price)       # callback for observer
    if price > @limit
      print "+++ #{time.to_s}: Price above #@limit: #{price}\n"
    end
  end
end

ticker = Ticker.new("MSFT")
WarnLow.new(ticker, 80)
WarnHigh.new(ticker, 120)
ticker.run

Produces:

Current price: 83
Current price: 75
--- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 75
Current price: 90
Current price: 134
+++ Sun Jun 09 00:10:25 CDT 2002: Price above 120: 134
Current price: 134
Current price: 112
Current price: 79
--- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 79

In Files

  • lib/observer.rb

Public Instance Methods

add_observer(observer, func=:update) click to toggle source

Add observer as an observer on this object. so that it will receive notifications.

observer

the object that will be notified of changes.

func

Symbol naming the method that will be called when this Observable has changes.

This method must return true for observer.respond_to? and will receive *arg when notify_observers is called, where *arg is the value passed to notify_observers by this Observable

# File lib/observer.rb, line 126
def add_observer(observer, func=:update)
  @observer_peers = {} unless defined? @observer_peers
  unless observer.respond_to? func
    raise NoMethodError, "observer does not respond to `#{func.to_s}'"
  end
  @observer_peers[observer] = func
end
changed(state=true) click to toggle source

Set the changed state of this object. Notifications will be sent only if the changed state is true.

state

Boolean indicating the changed state of this Observable.

# File lib/observer.rb, line 167
def changed(state=true)
  @observer_state = state
end
changed?() click to toggle source

Returns true if this object's state has been changed since the last notify_observers call.

# File lib/observer.rb, line 175
def changed?
  if defined? @observer_state and @observer_state
    true
  else
    false
  end
end
count_observers() click to toggle source

Return the number of observers associated with this object.

# File lib/observer.rb, line 153
def count_observers
  if defined? @observer_peers
    @observer_peers.size
  else
    0
  end
end
delete_observer(observer) click to toggle source

Remove observer as an observer on this object so that it will no longer receive notifications.

observer

An observer of this Observable

# File lib/observer.rb, line 139
def delete_observer(observer)
  @observer_peers.delete observer if defined? @observer_peers
end
delete_observers() click to toggle source

Remove all observers associated with this object.

# File lib/observer.rb, line 146
def delete_observers
  @observer_peers.clear if defined? @observer_peers
end
notify_observers(*arg) click to toggle source

Notify observers of a change in state if this object's changed state is true.

This will invoke the method named in add_observer, passing *arg. The changed state is then set to false.

*arg

Any arguments to pass to the observers.

# File lib/observer.rb, line 191
def notify_observers(*arg)
  if defined? @observer_state and @observer_state
    if defined? @observer_peers
      @observer_peers.each do |k, v|
        k.send v, *arg
      end
    end
    @observer_state = false
  end
end


module Open3 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Open3

Open3 grants you access to stdin, stdout, stderr and a thread to wait the child process when running another program. You can specify various attributes, redirections, current directory, etc., of the program as Process.spawn.

  • ::popen3 : pipes for stdin, stdout, stderr

  • ::popen2 : pipes for stdin, stdout

  • ::popen2e : pipes for stdin, merged stdout and stderr

  • ::capture3 : give a string for stdin. get strings for stdout, stderr

  • ::capture2 : give a string for stdin. get a string for stdout

  • ::capture2e : give a string for stdin. get a string for merged stdout and stderr

  • ::pipeline_rw : pipes for first stdin and last stdout of a pipeline

  • ::pipeline_r : pipe for last stdout of a pipeline

  • ::pipeline_w : pipe for first stdin of a pipeline

  • ::pipeline_start : run a pipeline and don't wait

  • ::pipeline : run a pipeline and wait

In Files

  • lib/open3.rb

Public Class Methods

capture2(*cmd) click to toggle source

::capture2 captures the standard output of a command.

stdout_str, status = Open3.capture2([env,] cmd... [, opts])

The arguments env, cmd and opts are passed to ::popen3 except opts and opts. See Process.spawn.

If opts is specified, it is sent to the command's standard input.

If opts is true, internal pipes are set to binary mode.

Example:

# factor is a command for integer factorization.
o, s = Open3.capture2("factor", :stdin_data=>"42")
p o #=> "42: 2 3 7\n"

# generate x**2 graph in png using gnuplot.
gnuplot_commands = <<"End"
  set terminal png
  plot x**2, "-" with lines
  1 14
  2 1
  3 8
  4 5
  e
End
image, s = Open3.capture2("gnuplot", :stdin_data=>gnuplot_commands, :binmode=>true)

# File lib/open3.rb, line 323
def capture2(*cmd)
  if Hash === cmd.last
    opts = cmd.pop.dup
  else
    opts = {}
  end

  stdin_data = opts.delete(:stdin_data) || ''
  binmode = opts.delete(:binmode)

  popen2(*cmd, opts) {|i, o, t|
    if binmode
      i.binmode
      o.binmode
    end
    out_reader = Thread.new { o.read }
    i.write stdin_data
    i.close
    [out_reader.value, t.value]
  }
end
capture2e(*cmd) click to toggle source

::capture2e captures the standard output and the standard error of a command.

stdout_and_stderr_str, status = Open3.capture2e([env,] cmd... [, opts])

The arguments env, cmd and opts are passed to ::popen3 except opts and opts. See Process.spawn.

If opts is specified, it is sent to the command's standard input.

If opts is true, internal pipes are set to binary mode.

Example:

# capture make log
make_log, s = Open3.capture2e("make")
# File lib/open3.rb, line 362
def capture2e(*cmd)
  if Hash === cmd.last
    opts = cmd.pop.dup
  else
    opts = {}
  end

  stdin_data = opts.delete(:stdin_data) || ''
  binmode = opts.delete(:binmode)

  popen2e(*cmd, opts) {|i, oe, t|
    if binmode
      i.binmode
      oe.binmode
    end
    outerr_reader = Thread.new { oe.read }
    i.write stdin_data
    i.close
    [outerr_reader.value, t.value]
  }
end
capture3(*cmd) click to toggle source

::capture3 captures the standard output and the standard error of a command.

stdout_str, stderr_str, status = Open3.capture3([env,] cmd... [, opts])

The arguments env, cmd and opts are passed to ::popen3 except opts and opts. See Process.spawn.

If opts is specified, it is sent to the command's standard input.

If opts is true, internal pipes are set to binary mode.

Example:

# dot is a command of graphviz.
graph = <<'End'
  digraph g {
    a -> b
  }
End
layouted_graph, dot_log = Open3.capture3("dot -v", :stdin_data=>graph)

o, e, s = Open3.capture3("echo abc; sort >&2", :stdin_data=>"foo\nbar\nbaz\n")
p o #=> "abc\n"
p e #=> "bar\nbaz\nfoo\n"
p s #=> #<Process::Status: pid 32682 exit 0>

# generate a thumnail image using the convert command of ImageMagick.
# However, if the image stored really in a file,
# system("convert", "-thumbnail", "80", "png:#{filename}", "png:-") is better
# because memory consumption.
# But if the image is stored in a DB or generated by gnuplot Open3.capture2 example,
# Open3.capture3 is considerable.
#
image = File.read("/usr/share/openclipart/png/animals/mammals/sheep-md-v0.1.png", :binmode=>true)
thumnail, err, s = Open3.capture3("convert -thumbnail 80 png:- png:-", :stdin_data=>image, :binmode=>true)
if s.success?
  STDOUT.binmode; print thumnail
end

# File lib/open3.rb, line 269
def capture3(*cmd)
  if Hash === cmd.last
    opts = cmd.pop.dup
  else
    opts = {}
  end

  stdin_data = opts.delete(:stdin_data) || ''
  binmode = opts.delete(:binmode)

  popen3(*cmd, opts) {|i, o, e, t|
    if binmode
      i.binmode
      o.binmode
      e.binmode
    end
    out_reader = Thread.new { o.read }
    err_reader = Thread.new { e.read }
    i.write stdin_data
    i.close
    [out_reader.value, err_reader.value, t.value]
  }
end
pipeline(*cmds) click to toggle source

::pipeline starts a list of commands as a pipeline. It waits the finish of the commands. No pipe made for stdin of the first command and stdout of the last command.

status_list = Open3.pipeline(cmd1, cmd2, ... [, opts])

Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.

cmd:
  commandline                              command line string which is passed to a shell
  [env, commandline, opts]                 command line string which is passed to a shell
  [env, cmdname, arg1, ..., opts]          command name and one or more arguments (no shell)
  [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)

Note that env and opts are optional, as Process.spawn.

Example:

fname = "/usr/share/man/man1/ruby.1.gz"
p Open3.pipeline(["zcat", fname], "nroff -man", "less")
#=> [#<Process::Status: pid 11817 exit 0>,
#    #<Process::Status: pid 11820 exit 0>,
#    #<Process::Status: pid 11828 exit 0>]

fname = "/usr/share/man/man1/ls.1.gz"
Open3.pipeline(["zcat", fname], "nroff -man", "colcrt")

# convert PDF to PS and send to a printer by lpr
pdf_file = "paper.pdf"
printer = "printer-name"
Open3.pipeline(["pdftops", pdf_file, "-"],
               ["lpr", "-P#{printer}"])

# count lines
Open3.pipeline("sort", "uniq -c", :in=>"names.txt", :out=>"count")

# cyclic pipeline
r,w = IO.pipe
w.print "ibase=14\n10\n"
Open3.pipeline("bc", "tee /dev/tty", :in=>r, :out=>w)
#=> 14
#   18
#   22
#   30
#   42
#   58
#   78
#   106
#   202

# File lib/open3.rb, line 652
def pipeline(*cmds)
  if Hash === cmds.last
    opts = cmds.pop.dup
  else
    opts = {}
  end

  pipeline_run(cmds, opts, [], []) {|ts|
    ts.map {|t| t.value }
  }
end
pipeline_r(*cmds, &block) click to toggle source

::pipeline_r starts a list of commands as a pipeline with a pipe which connects stdout of the last command.

Open3.pipeline_r(cmd1, cmd2, ... [, opts]) {|last_stdout, wait_threads|
  ...
}

last_stdout, wait_threads = Open3.pipeline_r(cmd1, cmd2, ... [, opts])
...
last_stdout.close

Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.

cmd:
  commandline                              command line string which is passed to a shell
  [env, commandline, opts]                 command line string which is passed to a shell
  [env, cmdname, arg1, ..., opts]          command name and one or more arguments (no shell)
  [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)

Note that env and opts are optional, as Process.spawn.

Example:

Open3.pipeline_r("zcat /var/log/apache2/access.log.*.gz",
                 [{"LANG"=>"C"}, "grep", "GET /favicon.ico"],
                 "logresolve") {|o, ts|
  o.each_line {|line|
    ...
  }
}

Open3.pipeline_r("yes", "head -10") {|o, ts|
  p o.read      #=> "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"
  p ts[0].value #=> #<Process::Status: pid 24910 SIGPIPE (signal 13)>
  p ts[1].value #=> #<Process::Status: pid 24913 exit 0>
}

# File lib/open3.rb, line 483
def pipeline_r(*cmds, &block)
  if Hash === cmds.last
    opts = cmds.pop.dup
  else
    opts = {}
  end

  out_r, out_w = IO.pipe
  opts[:out] = out_w

  pipeline_run(cmds, opts, [out_w], [out_r], &block)
end
pipeline_rw(*cmds, &block) click to toggle source

::pipeline_rw starts a list of commands as a pipeline with pipes which connects stdin of the first command and stdout of the last command.

Open3.pipeline_rw(cmd1, cmd2, ... [, opts]) {|first_stdin, last_stdout, wait_threads|
  ...
}

first_stdin, last_stdout, wait_threads = Open3.pipeline_rw(cmd1, cmd2, ... [, opts])
...
first_stdin.close
last_stdout.close

Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.

cmd:
  commandline                              command line string which is passed to a shell
  [env, commandline, opts]                 command line string which is passed to a shell
  [env, cmdname, arg1, ..., opts]          command name and one or more arguments (no shell)
  [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)

Note that env and opts are optional, as Process.spawn.

The option to pass Process.spawn is constructed by merging opts, the last hash element of the array and specification for the pipe between each commands.

Example:

Open3.pipeline_rw("tr -dc A-Za-z", "wc -c") {|i,o,ts|
  i.puts "All persons more than a mile high to leave the court."
  i.close
  p o.gets #=> "42\n"
}

Open3.pipeline_rw("sort", "cat -n") {|stdin, stdout, wait_thrs|
  stdin.puts "foo"
  stdin.puts "bar"
  stdin.puts "baz"
  stdin.close     # send EOF to sort.
  p stdout.read   #=> "     1\tbar\n     2\tbaz\n     3\tfoo\n"
}

# File lib/open3.rb, line 427
def pipeline_rw(*cmds, &block)
  if Hash === cmds.last
    opts = cmds.pop.dup
  else
    opts = {}
  end

  in_r, in_w = IO.pipe
  opts[:in] = in_r
  in_w.sync = true

  out_r, out_w = IO.pipe
  opts[:out] = out_w

  pipeline_run(cmds, opts, [in_r, out_w], [in_w, out_r], &block)
end
pipeline_start(*cmds, &block) click to toggle source

::pipeline_start starts a list of commands as a pipeline. No pipe made for stdin of the first command and stdout of the last command.

Open3.pipeline_start(cmd1, cmd2, ... [, opts]) {|wait_threads|
  ...
}

wait_threads = Open3.pipeline_start(cmd1, cmd2, ... [, opts])
...

Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.

cmd:
  commandline                              command line string which is passed to a shell
  [env, commandline, opts]                 command line string which is passed to a shell
  [env, cmdname, arg1, ..., opts]          command name and one or more arguments (no shell)
  [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)

Note that env and opts are optional, as Process.spawn.

Example:

# run xeyes in 10 seconds.
Open3.pipeline_start("xeyes") {|ts|
  sleep 10
  t = ts[0]
  Process.kill("TERM", t.pid)
  p t.value #=> #<Process::Status: pid 911 SIGTERM (signal 15)>
}

# convert pdf to ps and send it to a printer.
# collect error message of pdftops and lpr.
pdf_file = "paper.pdf"
printer = "printer-name"
err_r, err_w = IO.pipe
Open3.pipeline_start(["pdftops", pdf_file, "-"],
                     ["lpr", "-P#{printer}"],
                     :err=>err_w) {|ts|
  err_w.close
  p err_r.read # error messages of pdftops and lpr.
}

# File lib/open3.rb, line 584
def pipeline_start(*cmds, &block)
  if Hash === cmds.last
    opts = cmds.pop.dup
  else
    opts = {}
  end

  if block
    pipeline_run(cmds, opts, [], [], &block)
  else
    ts, = pipeline_run(cmds, opts, [], [])
    ts
  end
end
pipeline_w(*cmds, &block) click to toggle source

::pipeline_w starts a list of commands as a pipeline with a pipe which connects stdin of the first command.

Open3.pipeline_w(cmd1, cmd2, ... [, opts]) {|first_stdin, wait_threads|
  ...
}

first_stdin, wait_threads = Open3.pipeline_w(cmd1, cmd2, ... [, opts])
...
first_stdin.close

Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.

cmd:
  commandline                              command line string which is passed to a shell
  [env, commandline, opts]                 command line string which is passed to a shell
  [env, cmdname, arg1, ..., opts]          command name and one or more arguments (no shell)
  [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)

Note that env and opts are optional, as Process.spawn.

Example:

Open3.pipeline_w("bzip2 -c", :out=>"/tmp/hello.bz2") {|i, ts|
  i.puts "hello"
}

# File lib/open3.rb, line 525
def pipeline_w(*cmds, &block)
  if Hash === cmds.last
    opts = cmds.pop.dup
  else
    opts = {}
  end

  in_r, in_w = IO.pipe
  opts[:in] = in_r
  in_w.sync = true

  pipeline_run(cmds, opts, [in_r], [in_w], &block)
end
popen2(*cmd, &block) click to toggle source

::popen2 is similer to ::popen3 except it doesn't make a pipe for the standard error stream.

Block form:

Open3.popen2([env,] cmd... [, opts]) {|stdin, stdout, wait_thr|
  pid = wait_thr.pid # pid of the started process.
  ...
  exit_status = wait_thr.value # Process::Status object returned.
}

Non-block form:

stdin, stdout, wait_thr = Open3.popen2([env,] cmd... [, opts])
...
stdin.close  # stdin and stdout should be closed explicitly in this form.
stdout.close

See Process.spawn for the optional hash arguments env and opts.

Example:

Open3.popen2("wc -c") {|i,o,t|
  i.print "answer to life the universe and everything"
  i.close
  p o.gets #=> "42\n"
}

Open3.popen2("bc -q") {|i,o,t|
  i.puts "obase=13"
  i.puts "6 * 9"
  p o.gets #=> "42\n"
}

Open3.popen2("dc") {|i,o,t|
  i.print "42P"
  i.close
  p o.read #=> "*"
}

# File lib/open3.rb, line 143
def popen2(*cmd, &block)
  if Hash === cmd.last
    opts = cmd.pop.dup
  else
    opts = {}
  end

  in_r, in_w = IO.pipe
  opts[:in] = in_r
  in_w.sync = true

  out_r, out_w = IO.pipe
  opts[:out] = out_w

  popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block)
end
popen2e(*cmd, &block) click to toggle source

::popen2e is similer to ::popen3 except it merges the standard output stream and the standard error stream.

Block form:

Open3.popen2e([env,] cmd... [, opts]) {|stdin, stdout_and_stderr, wait_thr|
  pid = wait_thr.pid # pid of the started process.
  ...
  exit_status = wait_thr.value # Process::Status object returned.
}

Non-block form:

stdin, stdout_and_stderr, wait_thr = Open3.popen2e([env,] cmd... [, opts])
...
stdin.close  # stdin and stdout_and_stderr should be closed explicitly in this form.
stdout_and_stderr.close

See Process.spawn for the optional hash arguments env and opts.

Example:

# check gcc warnings
source = "foo.c"
Open3.popen2e("gcc", "-Wall", source) {|i,oe,t|
  oe.each {|line|
    if /warning/ =~ line
      ...
    end
  }
}

# File lib/open3.rb, line 192
def popen2e(*cmd, &block)
  if Hash === cmd.last
    opts = cmd.pop.dup
  else
    opts = {}
  end

  in_r, in_w = IO.pipe
  opts[:in] = in_r
  in_w.sync = true

  out_r, out_w = IO.pipe
  opts[[:out, :err]] = out_w

  popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block)
end
popen3(*cmd, &block) click to toggle source

Open stdin, stdout, and stderr streams and start external executable. In addition, a thread for waiting the started process is noticed. The thread has a pid method and thread variable :pid which is the pid of the started process.

Block form:

Open3.popen3([env,] cmd... [, opts]) {|stdin, stdout, stderr, wait_thr|
  pid = wait_thr.pid # pid of the started process.
  ...
  exit_status = wait_thr.value # Process::Status object returned.
}

Non-block form:

stdin, stdout, stderr, wait_thr = Open3.popen3([env,] cmd... [, opts])
pid = wait_thr[:pid]  # pid of the started process.
...
stdin.close  # stdin, stdout and stderr should be closed explicitly in this form.
stdout.close
stderr.close
exit_status = wait_thr.value  # Process::Status object returned.

The parameters cmd... is passed to Process.spawn. So a commandline string and list of argument strings can be accepted as follows.

Open3.popen3("echo abc") {|i, o, e, t| ... }
Open3.popen3("echo", "abc") {|i, o, e, t| ... }
Open3.popen3(["echo", "argv0"], "abc") {|i, o, e, t| ... }

If the last parameter, opts, is a Hash, it is recognized as an option for Process.spawn.

Open3.popen3("pwd", :chdir=>"/") {|i,o,e,t|
  p o.read.chomp #=> "/"
}

wait_thr.value waits the termination of the process. The block form also waits the process when it returns.

Closing stdin, stdout and stderr does not wait the process.

You should be careful to avoid deadlocks. Since pipes are fixed length buffer, ::popen3(“prog”) {|i, o, e, t| o.read } deadlocks if the program generates many output on stderr. You should be read stdout and stderr simultaneously (using thread or IO.select). However if you don't need stderr output, ::popen2 can be used. If merged stdout and stderr output is not a problem, you can use ::popen2e. If you really needs stdout and stderr output as separate strings, you can consider ::capture3.

# File lib/open3.rb, line 82
def popen3(*cmd, &block)
  if Hash === cmd.last
    opts = cmd.pop.dup
  else
    opts = {}
  end

  in_r, in_w = IO.pipe
  opts[:in] = in_r
  in_w.sync = true

  out_r, out_w = IO.pipe
  opts[:out] = out_w

  err_r, err_w = IO.pipe
  opts[:err] = err_w

  popen_run(cmd, opts, [in_r, out_w, err_w], [in_w, out_r, err_r], &block)
end


module OpenSSL - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL

OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the OpenSSL library.

Examples

All examples assume you have loaded OpenSSL with:

require 'openssl'

These examples build atop each other. For example the key created in the next is used in throughout these examples.

Keys

Creating a Key

This example creates a 2048 bit RSA keypair and writes it to the current directory.

key = OpenSSL::PKey::RSA.new 2048

open 'private_key.pem', 'w' do |io| io.write key.to_pem end
open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end

Exporting a Key

Keys saved to disk without encryption are not secure as anyone who gets ahold of the key may use it unless it is encrypted. In order to securely export a key you may export it with a pass phrase.

cipher = OpenSSL::Cipher.new 'AES-128-CBC'
pass_phrase = 'my secure pass phrase goes here'

key_secure = key.export cipher, pass_phrase

open 'private.secure.pem', 'w' do |io|
  io.write key_secure
end

OpenSSL::Cipher.ciphers returns a list of available ciphers.

Loading a Key

A key can also be loaded from a file.

key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
key2.public? # => true

or

key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
key3.private? # => false

Loading an Encrypted Key

OpenSSL will prompt you for your pass phrase when loading an encrypted key. If you will not be able to type in the pass phrase you may provide it when loading the key:

key4_pem = File.read 'private.secure.pem'
key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase

RSA Encryption

RSA provides encryption and decryption using the public and private keys. You can use a variety of padding methods depending upon the intended use of encrypted data.

Encryption & Decryption

Asymmetric public/private key encryption is slow and victim to attack in cases where it is used without padding or directly to encrypt larger chunks of data. Typical use cases for RSA encryption involve “wrapping” a symmetric key with the public key of the recipient who would “unwrap” that symmetric key again using their private key. The following illustrates a simplified example of such a key transport scheme. It shouldn't be used in practice, though, standardized protocols should always be preferred.

wrapped_key = key.public_encrypt key

A symmetric key encrypted with the public key can only be decrypted with the corresponding private key of the recipient.

original_key = key.private_decrypt wrapped_key

By default PKCS#1 padding will be used, but it is also possible to use other forms of padding, see PKey::RSA for further details.

Signatures

Using “private_encrypt” to encrypt some data with the private key is equivalent to applying a digital signature to the data. A verifying party may validate the signature by comparing the result of decrypting the signature with “public_decrypt” to the original data. However, OpenSSL::PKey already has methods “sign” and “verify” that handle digital signatures in a standardized way - “private_encrypt” and “public_decrypt” shouldn't be used in practice.

To sign a document, a cryptographically secure hash of the document is computed first, which is then signed using the private key.

digest = OpenSSL::Digest::SHA256.new
signature = key.sign digest, document

To validate the signature, again a hash of the document is computed and the signature is decrypted using the public key. The result is then compared to the hash just computed, if they are equal the signature was valid.

digest = OpenSSL::Digest::SHA256.new
if key.verify digest, signature, document
  puts 'Valid'
else
  puts 'Invalid'
end

PBKDF2 Password-based Encryption

If supported by the underlying OpenSSL version used, Password-based Encryption should use the features of PKCS5. If not supported or if required by legacy applications, the older, less secure methods specified in RFC 2898 are also supported (see below).

PKCS5 supports PBKDF2 as it was specified in PKCS#5 v2.0. It still uses a password, a salt, and additionally a number of iterations that will slow the key derivation process down. The slower this is, the more work it requires being able to brute-force the resulting key.

Encryption

The strategy is to first instantiate a Cipher for encryption, and then to generate a random IV plus a key derived from the password using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt, the number of iterations largely depends on the hardware being used.

cipher = OpenSSL::Cipher.new 'AES-128-CBC'
cipher.encrypt
iv = cipher.random_iv

pwd = 'some hopefully not to easily guessable password'
salt = OpenSSL::Random.random_bytes 16
iter = 20000
key_len = cipher.key_len
digest = OpenSSL::Digest::SHA256.new

key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
cipher.key = key

Now encrypt the data:

encrypted = cipher.update document
encrypted << cipher.final

Decryption

Use the same steps as before to derive the symmetric AES key, this time setting the Cipher up for decryption.

cipher = OpenSSL::Cipher.new 'AES-128-CBC'
cipher.decrypt
cipher.iv = iv # the one generated with #random_iv

pwd = 'some hopefully not to easily guessable password'
salt = ... # the one generated above
iter = 20000
key_len = cipher.key_len
digest = OpenSSL::Digest::SHA256.new

key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
cipher.key = key

Now decrypt the data:

decrypted = cipher.update encrypted
decrypted << cipher.final

PKCS #5 Password-based Encryption

PKCS #5 is a password-based encryption standard documented at RFC2898. It allows a short password or passphrase to be used to create a secure encryption key. If possible, PBKDF2 as described above should be used if the circumstances allow it.

PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption key.

pass_phrase = 'my secure pass phrase goes here'
salt = '8 octets'

Encryption

First set up the cipher for encryption

encrypter = OpenSSL::Cipher.new 'AES-128-CBC'
encrypter.encrypt
encrypter.pkcs5_keyivgen pass_phrase, salt

Then pass the data you want to encrypt through

encrypted = encrypter.update 'top secret document'
encrypted << encrypter.final

Decryption

Use a new Cipher instance set up for decryption

decrypter = OpenSSL::Cipher.new 'AES-128-CBC'
decrypter.decrypt
decrypter.pkcs5_keyivgen pass_phrase, salt

Then pass the data you want to decrypt through

plain = decrypter.update encrypted
plain << decrypter.final

X509 Certificates

Creating a Certificate

This example creates a self-signed certificate using an RSA key and a SHA1 signature.

name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'

cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = 0
cert.not_before = Time.now
cert.not_after = Time.now + 3600

cert.public_key = key.public_key
cert.subject = name

Certificate Extensions

You can add extensions to the certificate with OpenSSL::SSL::ExtensionFactory to indicate the purpose of the certificate.

extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert

cert.add_extension \
  extension_factory.create_extension('basicConstraints', 'CA:FALSE', true)

cert.add_extension \
  extension_factory.create_extension(
    'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')

cert.add_extension \
  extension_factory.create_extension('subjectKeyIdentifier', 'hash')

The list of supported extensions (and in some cases their possible values) can be derived from the “objects.h” file in the OpenSSL source code.

Signing a Certificate

To sign a certificate set the issuer and use OpenSSL::X509::Certificate#sign with a digest algorithm. This creates a self-signed cert because we're using the same name and key to sign the certificate as was used to create the certificate.

cert.issuer = name
cert.sign key, OpenSSL::Digest::SHA1.new

open 'certificate.pem', 'w' do |io| io.write cert.to_pem end

Loading a Certificate

Like a key, a cert can also be loaded from a file.

cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem'

Verifying a Certificate

Certificate#verify will return true when a certificate was signed with the given public key.

raise 'certificate can not be verified' unless cert2.verify key

Certificate Authority

A certificate authority (CA) is a trusted third party that allows you to verify the ownership of unknown certificates. The CA issues key signatures that indicate it trusts the user of that key. A user encountering the key can verify the signature by using the CA's public key.

CA Key

CA keys are valuable, so we encrypt and save it to disk and make sure it is not readable by other users.

ca_key = OpenSSL::PKey::RSA.new 2048

cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'

open 'ca_key.pem', 'w', 0400 do |io|
  io.write key.export(cipher, pass_phrase)
end

CA Certificate

A CA certificate is created the same way we created a certificate above, but with different extensions.

ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'

ca_cert = OpenSSL::X509::Certificate.new
ca_cert.serial = 0
ca_cert.version = 2
ca_cert.not_before = Time.now
ca_cert.not_after = Time.now + 86400

ca_cert.public_key = ca_key.public_key
ca_cert.subject = ca_name
ca_cert.issuer = ca_name

extension_factory = OpenSSL::X509::ExtensionFactory.new
extension_factory.subject_certificate = ca_cert
extension_factory.issuer_certificate = ca_cert

ca_cert.add_extension \
  extension_factory.create_extension('subjectKeyIdentifier', 'hash')

This extension indicates the CA's key may be used as a CA.

ca_cert.add_extension \
  extension_factory.create_extension('basicConstraints', 'CA:TRUE', true)

This extension indicates the CA's key may be used to verify signatures on both certificates and certificate revocations.

ca_cert.add_extension \
  extension_factory.create_extension(
    'keyUsage', 'cRLSign,keyCertSign', true)

Root CA certificates are self-signed.

ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new

The CA certificate is saved to disk so it may be distributed to all the users of the keys this CA will sign.

open 'ca_cert.pem', 'w' do |io|
  io.write ca_cert.to_pem
end

Certificate Signing Request

The CA signs keys through a Certificate Signing Request (CSR). The CSR contains the information necessary to identify the key.

csr = OpenSSL::X509::Request.new
csr.version = 0
csr.subject = name
csr.public_key = key.public_key
csr.sign key, OpenSSL::Digest::SHA1.new

A CSR is saved to disk and sent to the CA for signing.

open 'csr.pem', 'w' do |io|
  io.write csr.to_pem
end

Creating a Certificate from a CSR

Upon receiving a CSR the CA will verify it before signing it. A minimal verification would be to check the CSR's signature.

csr = OpenSSL::X509::Request.new File.read 'csr.pem'

raise 'CSR can not be verified' unless csr.verify csr.public_key

After verification a certificate is created, marked for various usages, signed with the CA key and returned to the requester.

csr_cert = OpenSSL::X509::Certificate.new
csr_cert.serial = 0
csr_cert.version = 2
csr_cert.not_before = Time.now
csr_cert.not_after = Time.now + 600

csr_cert.subject = csr.subject
csr_cert.public_key = csr.public_key
csr_cert.issuer = ca_cert.subject

extension_factory = OpenSSL::X509::ExtensionFactory.new
extension_factory.subject_certificate = csr_cert
extension_factory.issuer_certificate = ca_cert

csr_cert.add_extension    extension_factory.create_extension('basicConstraints', 'CA:FALSE')

csr_cert.add_extension    extension_factory.create_extension(
    'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')

csr_cert.add_extension    extension_factory.create_extension('subjectKeyIdentifier', 'hash')

csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new

open 'csr_cert.pem', 'w' do |io|
  io.write csr_cert.to_pem
end

SSL and TLS Connections

Using our created key and certificate we can create an SSL or TLS connection. An SSLContext is used to set up an SSL session.

context = OpenSSL::SSL::SSLContext.new

SSL Server

An SSL server requires the certificate and private key to communicate securely with its clients:

context.cert = cert
context.key = key

Then create an SSLServer with a TCP server socket and the context. Use the SSLServer like an ordinary TCP server.

require 'socket'

tcp_server = TCPServer.new 5000
ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context

loop do
  ssl_connection = ssl_server.accept

  data = connection.gets

  response = "I got #{data.dump}"
  puts response

  connection.puts "I got #{data.dump}"
  connection.close
end

SSL client

An SSL client is created with a TCP socket and the context. SSLSocket#connect must be called to initiate the SSL handshake and start encryption. A key and certificate are not required for the client socket.

require 'socket'

tcp_client = TCPSocket.new 'localhost', 5000
ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
ssl_client.connect

ssl_client.puts "hello server!"
puts ssl_client.gets

Peer Verification

An unverified SSL connection does not provide much security. For enhanced security the client or server can verify the certificate of its peer.

The client can be modified to verify the server's certificate against the certificate authority's certificate:

context.ca_file = 'ca_cert.pem'
context.verify_mode = OpenSSL::SSL::VERIFY_PEER

require 'socket'

tcp_client = TCPSocket.new 'localhost', 5000
ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
ssl_client.connect

ssl_client.puts "hello server!"
puts ssl_client.gets

If the server certificate is invalid or context.ca_file is not set when verifying peers an OpenSSL::SSL::SSLError will be raised.

In Files

  • lib/rubygems/security.rb
  • ext/openssl/lib/openssl/bn.rb
  • ext/openssl/lib/openssl/cipher.rb
  • ext/openssl/lib/openssl/config.rb
  • ext/openssl/lib/openssl/digest.rb
  • ext/openssl/lib/openssl/ssl.rb
  • ext/openssl/lib/openssl/x509.rb
  • ext/openssl/ossl.c
  • ext/openssl/ossl_asn1.c
  • ext/openssl/ossl_bn.c
  • ext/openssl/ossl_cipher.c
  • ext/openssl/ossl_digest.c
  • ext/openssl/ossl_hmac.c
  • ext/openssl/ossl_ns_spki.c
  • ext/openssl/ossl_pkcs5.c
  • ext/openssl/ossl_pkey.c
  • ext/openssl/ossl_pkey_dh.c
  • ext/openssl/ossl_pkey_dsa.c
  • ext/openssl/ossl_pkey_ec.c
  • ext/openssl/ossl_pkey_rsa.c
  • ext/openssl/ossl_rand.c
  • ext/openssl/ossl_ssl.c
  • ext/openssl/ossl_ssl_session.c
  • ext/openssl/ossl_x509cert.c
  • ext/openssl/ossl_x509store.c

Constants

OPENSSL_FIPS
OPENSSL_LIBRARY_VERSION

Version of OpenSSL the ruby OpenSSL extension is running with

OPENSSL_VERSION

Version of OpenSSL the ruby OpenSSL extension was built with

OPENSSL_VERSION_NUMBER

Version number of OpenSSL the ruby OpenSSL extension was built with (base 16)

VERSION

OpenSSL ruby extension version

Public Class Methods

Digest(name) click to toggle source

Returns a Digest subclass by name.

require 'openssl'

OpenSSL::Digest("MD5")
# => OpenSSL::Digest::MD5

Digest("Foo")
# => NameError: wrong constant name Foo

# File ext/openssl/lib/openssl/digest.rb, line 82
def Digest(name)
  OpenSSL::Digest.const_get(name)
end
debug → true | false click to toggle source
static VALUE
ossl_debug_get(VALUE self)
{
    return dOSSL;
}
debug = boolean → boolean click to toggle source

Turns on or off CRYPTO_MEM_CHECK. Also shows some debugging message on stderr.

static VALUE
ossl_debug_set(VALUE self, VALUE val)
{
    VALUE old = dOSSL;
    dOSSL = val;

    if (old != dOSSL) {
        if (dOSSL == Qtrue) {
            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
            fprintf(stderr, "OSSL_DEBUG: IS NOW ON!\n");
        } else if (old == Qtrue) {
            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
            fprintf(stderr, "OSSL_DEBUG: IS NOW OFF!\n");
        }
    }
    return val;
}
errors → [String...] click to toggle source

See any remaining errors held in queue.

Any errors you see here are probably due to a bug in ruby's OpenSSL implementation.

VALUE
ossl_get_errors()
{
    VALUE ary;
    long e;

    ary = rb_ary_new();
    while ((e = ERR_get_error()) != 0){
        rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL)));
    }

    return ary;
}
fips_mode = boolean → boolean click to toggle source

Turns FIPS mode on or off. Turning on FIPS mode will obviously only have an effect for FIPS-capable installations of the OpenSSL library. Trying to do so otherwise will result in an error.

Examples

OpenSSL.fips_mode = true # turn FIPS mode on OpenSSL.fips_mode = false # and off again

static VALUE
ossl_fips_mode_set(VALUE self, VALUE enabled)
{

#ifdef HAVE_OPENSSL_FIPS
    if (RTEST(enabled)) {
        int mode = FIPS_mode();
        if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
            ossl_raise(eOSSLError, "Turning on FIPS mode failed");
    } else {
        if(!FIPS_mode_set(0)) /* turning off twice is OK */
            ossl_raise(eOSSLError, "Turning off FIPS mode failed");
    }
    return enabled;
#else
    if (RTEST(enabled))
        ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode");
    return enabled;
#endif
}


module OpenSSL::ASN1 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::ASN1

Abstract Syntax Notation One (or ASN.1) is a notation syntax to describe data structures and is defined in ITU-T X.680. ASN.1 itself does not mandate any encoding or parsing rules, but usually ASN.1 data structures are encoded using the Distinguished Encoding Rules (DER) or less often the Basic Encoding Rules (BER) described in ITU-T X.690. DER and BER encodings are binary Tag-Length-Value (TLV) encodings that are quite concise compared to other popular data description formats such as XML, JSON etc. ASN.1 data structures are very common in cryptographic applications, e.g. X.509 public key certificates or certificate revocation lists (CRLs) are all defined in ASN.1 and DER-encoded. ASN.1, DER and BER are the building blocks of applied cryptography. The ASN1 module provides the necessary classes that allow generation of ASN.1 data structures and the methods to encode them using a DER encoding. The decode method allows parsing arbitrary BER-/DER-encoded data to a Ruby object that can then be modified and re-encoded at will.

ASN.1 class hierarchy

The base class representing ASN.1 structures is ASN1Data. ASN1Data offers attributes to read and set the tag, the tag_class and finally the value of a particular ASN.1 item. Upon parsing, any tagged values (implicit or explicit) will be represented by ASN1Data instances because their “real type” can only be determined using out-of-band information from the ASN.1 type declaration. Since this information is normally known when encoding a type, all sub-classes of ASN1Data offer an additional attribute tagging that allows to encode a value implicitly (:IMPLICIT) or explicitly (:EXPLICIT).

Constructive

Constructive is, as its name implies, the base class for all constructed encodings, i.e. those that consist of several values, opposed to “primitive” encodings with just one single value. Primitive values that are encoded with “infinite length” are typically constructed (their values come in multiple chunks) and are therefore represented by instances of Constructive. The value of an Constructive is always an Array.

ASN1::Set and ASN1::Sequence

The most common constructive encodings are SETs and SEQUENCEs, which is why there are two sub-classes of Constructive representing each of them.

Primitive

This is the super class of all primitive values. Primitive itself is not used when parsing ASN.1 data, all values are either instances of a corresponding sub-class of Primitive or they are instances of ASN1Data if the value was tagged implicitly or explicitly. Please cf. Primitive documentation for details on sub-classes and their respective mappings of ASN.1 data types to Ruby objects.

Possible values for tagging

When constructing an ASN1Data object the ASN.1 type definition may require certain elements to be either implicitly or explicitly tagged. This can be achieved by setting the tagging attribute manually for sub-classes of ASN1Data. Use the symbol :IMPLICIT for implicit tagging and :EXPLICIT if the element requires explicit tagging.

Possible values for tag_class

It is possible to create arbitrary ASN1Data objects that also support a PRIVATE or APPLICATION tag class. Possible values for the tag_class attribute are:

  • :UNIVERSAL (the default for untagged values)

  • :CONTEXT_SPECIFIC (the default for tagged values)

  • :APPLICATION

  • :PRIVATE

Tag constants

There is a constant defined for each universal tag:

  • OpenSSL::ASN1::EOC (0)

  • OpenSSL::ASN1::BOOLEAN (1)

  • OpenSSL::ASN1::INTEGER (2)

  • OpenSSL::ASN1::BIT_STRING (3)

  • OpenSSL::ASN1::OCTET_STRING (4)

  • OpenSSL::ASN1::NULL (5)

  • OpenSSL::ASN1::OBJECT (6)

  • OpenSSL::ASN1::ENUMERATED (10)

  • OpenSSL::ASN1::UTF8STRING (12)

  • OpenSSL::ASN1::SEQUENCE (16)

  • OpenSSL::ASN1::SET (17)

  • OpenSSL::ASN1::NUMERICSTRING (18)

  • OpenSSL::ASN1::PRINTABLESTRING (19)

  • OpenSSL::ASN1::T61STRING (20)

  • OpenSSL::ASN1::VIDEOTEXSTRING (21)

  • OpenSSL::ASN1::IA5STRING (22)

  • OpenSSL::ASN1::UTCTIME (23)

  • OpenSSL::ASN1::GENERALIZEDTIME (24)

  • OpenSSL::ASN1::GRAPHICSTRING (25)

  • OpenSSL::ASN1::ISO64STRING (26)

  • OpenSSL::ASN1::GENERALSTRING (27)

  • OpenSSL::ASN1::UNIVERSALSTRING (28)

  • OpenSSL::ASN1::BMPSTRING (30)

UNIVERSAL_TAG_NAME constant

An Array that stores the name of a given tag number. These names are the same as the name of the tag constant that is additionally defined, e.g. UNIVERSAL_TAG_NAME = “INTEGER” and OpenSSL::ASN1::INTEGER = 2.

Example usage

Decoding and viewing a DER-encoded file

require 'openssl'
require 'pp'
der = File.binread('data.der')
asn1 = OpenSSL::ASN1.decode(der)
pp der

Creating an ASN.1 structure and DER-encoding it

require 'openssl'
version = OpenSSL::ASN1::Integer.new(1)
# Explicitly 0-tagged implies context-specific tag class
serial = OpenSSL::ASN1::Integer.new(12345, 0, :EXPLICIT, :CONTEXT_SPECIFIC)
name = OpenSSL::ASN1::PrintableString.new('Data 1')
sequence = OpenSSL::ASN1::Sequence.new( [ version, serial, name ] )
der = sequence.to_der

In Files

  • ext/openssl/ossl.c

Constants

UNIVERSAL_TAG_NAME

Array storing tag names at the tag's index.

Public Class Methods

OpenSSL::ASN1.decode(der) → ASN1Data click to toggle source

Decodes a BER- or DER-encoded value and creates an ASN1Data instance. der may be a String or any object that features a #to_der method transforming it into a BER-/DER-encoded String.

Example

der = File.binread('asn1data')
asn1 = OpenSSL::ASN1.decode(der)
static VALUE
ossl_asn1_decode(VALUE self, VALUE obj)
{
    VALUE ret;
    unsigned char *p;
    volatile VALUE tmp;
    long len, read = 0, offset = 0;

    obj = ossl_to_der_if_possible(obj);
    tmp = rb_str_new4(StringValue(obj));
    p = (unsigned char *)RSTRING_PTR(tmp);
    len = RSTRING_LEN(tmp);
    ret = ossl_asn1_decode0(&p, len, &offset, 0, 0, &read);
    int_ossl_decode_sanity_check(len, read, offset);
    return ret;
}
OpenSSL::ASN1.decode_all(der) → Array of ASN1Data click to toggle source

Similar to decode with the difference that decode expects one distinct value represented in der. decode_all on the contrary decodes a sequence of sequential BER/DER values lined up in der and returns them as an array.

Example

ders = File.binread('asn1data_seq')
asn1_ary = OpenSSL::ASN1.decode_all(ders)
static VALUE
ossl_asn1_decode_all(VALUE self, VALUE obj)
{
    VALUE ary, val;
    unsigned char *p;
    long len, tmp_len = 0, read = 0, offset = 0;
    volatile VALUE tmp;

    obj = ossl_to_der_if_possible(obj);
    tmp = rb_str_new4(StringValue(obj));
    p = (unsigned char *)RSTRING_PTR(tmp);
    len = RSTRING_LEN(tmp);
    tmp_len = len;
    ary = rb_ary_new();
    while (tmp_len > 0) {
        long tmp_read = 0;
        val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read);
        rb_ary_push(ary, val);
        read += tmp_read;
        tmp_len -= tmp_read;
    }
    int_ossl_decode_sanity_check(len, read, offset);
    return ary;
}
OpenSSL::ASN1.traverse(asn1) → nil click to toggle source

If a block is given, it prints out each of the elements encountered. Block parameters are (in that order):

  • depth: The recursion depth, plus one with each constructed value being encountered (Number)

  • offset: Current byte offset (Number)

  • header length: Combined length in bytes of the Tag and Length headers. (Number)

  • length: The overall remaining length of the entire data (Number)

  • constructed: Whether this value is constructed or not (Boolean)

  • tag_class: Current tag class (Symbol)

  • tag: The current tag (Number)

Example

der = File.binread('asn1data.der')
OpenSSL::ASN1.traverse(der) do | depth, offset, header_len, length, constructed, tag_class, tag|
  puts "Depth: #{depth} Offset: #{offset} Length: #{length}"
  puts "Header length: #{header_len} Tag: #{tag} Tag class: #{tag_class} Constructed: #{constructed}"
end

static VALUE
ossl_asn1_traverse(VALUE self, VALUE obj)
{
    unsigned char *p;
    volatile VALUE tmp;
    long len, read = 0, offset = 0;

    obj = ossl_to_der_if_possible(obj);
    tmp = rb_str_new4(StringValue(obj));
    p = (unsigned char *)RSTRING_PTR(tmp);
    len = RSTRING_LEN(tmp);
    ossl_asn1_decode0(&p, len, &offset, 0, 1, &read);
    int_ossl_decode_sanity_check(len, read, offset);
    return Qnil;
}


class OpenSSL::ASN1::ASN1Data - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::ASN1::ASN1Data

The top-level class representing any ASN.1 object. When parsed by OpenSSL::ASN1.decode, tagged values are always represented by an instance of ASN1Data.

The role of ASN1Data for parsing tagged values

When encoding an ASN.1 type it is inherently clear what original type (e.g. INTEGER, OCTET STRING etc.) this value has, regardless of its tagging. But opposed to the time an ASN.1 type is to be encoded, when parsing them it is not possible to deduce the “real type” of tagged values. This is why tagged values are generally parsed into ASN1Data instances, but with a different outcome for implicit and explicit tagging.

Example of a parsed implicitly tagged value

An implicitly 1-tagged INTEGER value will be parsed as an ASN1Data with

  • tag equal to 1

  • tag_class equal to :CONTEXT_SPECIFIC

  • value equal to a String that carries the raw encoding of the INTEGER.

This implies that a subsequent decoding step is required to completely decode implicitly tagged values.

Example of a parsed explicitly tagged value

An explicitly 1-tagged INTEGER value will be parsed as an ASN1Data with

  • tag equal to 1

  • tag_class equal to :CONTEXT_SPECIFIC

  • value equal to an Array with one single element, an instance of OpenSSL::ASN1::Integer, i.e. the inner element is the non-tagged primitive value, and the tagging is represented in the outer ASN1Data

Example - Decoding an implicitly tagged INTEGER

int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT) # implicit 0-tagged
seq = OpenSSL::ASN1::Sequence.new( [int] )
der = seq.to_der
asn1 = OpenSSL::ASN1.decode(der)
# pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
#              @infinite_length=false,
#              @tag=16,
#              @tag_class=:UNIVERSAL,
#              @tagging=nil,
#              @value=
#                [#<OpenSSL::ASN1::ASN1Data:0x87326f4
#                   @infinite_length=false,
#                   @tag=0,
#                   @tag_class=:CONTEXT_SPECIFIC,
#                   @value="\x01">]>
raw_int = asn1.value[0]
# manually rewrite tag and tag class to make it an UNIVERSAL value
raw_int.tag = OpenSSL::ASN1::INTEGER
raw_int.tag_class = :UNIVERSAL
int2 = OpenSSL::ASN1.decode(raw_int)
puts int2.value # => 1

Example - Decoding an explicitly tagged INTEGER

int = OpenSSL::ASN1::Integer.new(1, 0, :EXPLICIT) # explicit 0-tagged
seq = OpenSSL::ASN1::Sequence.new( [int] )
der = seq.to_der
asn1 = OpenSSL::ASN1.decode(der)
# pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
#              @infinite_length=false,
#              @tag=16,
#              @tag_class=:UNIVERSAL,
#              @tagging=nil,
#              @value=
#                [#<OpenSSL::ASN1::ASN1Data:0x87326f4
#                   @infinite_length=false,
#                   @tag=0,
#                   @tag_class=:CONTEXT_SPECIFIC,
#                   @value=
#                     [#<OpenSSL::ASN1::Integer:0x85bf308
#                        @infinite_length=false,
#                        @tag=2,
#                        @tag_class=:UNIVERSAL
#                        @tagging=nil,
#                        @value=1>]>]>
int2 = asn1.value[0].value[0]
puts int2.value # => 1

In Files

  • ext/openssl/ossl_asn1.c

Parent

Object

Attributes

infinite_length[RW]

Never nil. A Boolean indicating whether the encoding was infinite length (in the case of parsing) or whether an infinite length encoding shall be used (in the encoding case). In DER, every value has a finite length associated with it. But in scenarios where large amounts of data need to be transferred it might be desirable to have some kind of streaming support available. For example, huge OCTET STRINGs are preferably sent in smaller-sized chunks, each at a time. This is possible in BER by setting the length bytes of an encoding to zero and by this indicating that the following value will be sent in chunks. Infinite length encodings are always constructed. The end of such a stream of chunks is indicated by sending a EOC (End of Content) tag. SETs and SEQUENCEs may use an infinite length encoding, but also primitive types such as e.g. OCTET STRINGS or BIT STRINGS may leverage this functionality (cf. ITU-T X.690).

tag[RW]

A Number representing the tag number of this ASN1Data. Never nil.

tag_class[RW]

A Symbol representing the tag class of this ASN1Data. Never nil. See ASN1Data for possible values.

value[RW]

Carries the value of a ASN.1 type. Please confer Constructive and Primitive for the mappings between ASN.1 data types and Ruby classes.

Public Class Methods

OpenSSL::ASN1::ASN1Data.new(value, tag, tag_class) → ASN1Data click to toggle source

value: Please have a look at Constructive and Primitive to see how Ruby types are mapped to ASN.1 types and vice versa.

tag: A Number indicating the tag number.

tag_class: A Symbol indicating the tag class. Please cf. ASN1 for possible values.

Example

asn1_int = OpenSSL::ASN1Data.new(42, 2, :UNIVERSAL) # => Same as OpenSSL::ASN1::Integer.new(42)
tagged_int = OpenSSL::ASN1Data.new(42, 0, :CONTEXT_SPECIFIC) # implicitly 0-tagged INTEGER

static VALUE
ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
{
    if(!SYMBOL_P(tag_class))
        ossl_raise(eASN1Error, "invalid tag class");
    if((SYM2ID(tag_class) == sUNIVERSAL) && NUM2INT(tag) > 31)
        ossl_raise(eASN1Error, "tag number for Universal too large");
    ossl_asn1_set_tag(self, tag);
    ossl_asn1_set_value(self, value);
    ossl_asn1_set_tag_class(self, tag_class);
    ossl_asn1_set_infinite_length(self, Qfalse);

    return self;
}

Public Instance Methods

to_der → DER-encoded String click to toggle source

Encodes this ASN1Data into a DER-encoded String value. The result is DER-encoded except for the possibility of infinite length encodings. Infinite length encodings are not allowed in strict DER, so strictly speaking the result of such an encoding would be a BER-encoding.

static VALUE
ossl_asn1data_to_der(VALUE self)
{
    VALUE value, der, inf_length;
    int tag, tag_class, is_cons = 0;
    long length;
    unsigned char *p;

    value = ossl_asn1_get_value(self);
    if(rb_obj_is_kind_of(value, rb_cArray)){
        is_cons = 1;
        value = join_der(value);
    }
    StringValue(value);

    tag = ossl_asn1_tag(self);
    tag_class = ossl_asn1_tag_class(self);
    inf_length = ossl_asn1_get_infinite_length(self);
    if (inf_length == Qtrue) {
        is_cons = 2;
    }
    if((length = ossl_asn1_object_size(is_cons, RSTRING_LENINT(value), tag)) <= 0)
        ossl_raise(eASN1Error, NULL);
    der = rb_str_new(0, length);
    p = (unsigned char *)RSTRING_PTR(der);
    ossl_asn1_put_object(&p, is_cons, RSTRING_LENINT(value), tag, tag_class);
    memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
    p += RSTRING_LEN(value);
    ossl_str_adjust(der, p);

    return der;
}


class OpenSSL::ASN1::ASN1Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::ASN1::ASN1Error

Generic error class for all errors raised in ASN1 and any of the classes defined in it.

In Files

  • ext/openssl/ossl_asn1.c

Parent

eOSSLError


class OpenSSL::ASN1::Constructive - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::ASN1::Constructive

The parent class for all constructed encodings. The value attribute of a Constructive is always an Array. Attributes are the same as for ASN1Data, with the addition of tagging.

SET and SEQUENCE

Most constructed encodings come in the form of a SET or a SEQUENCE. These encodings are represented by one of the two sub-classes of Constructive:

  • OpenSSL::ASN1::Set

  • OpenSSL::ASN1::Sequence

Please note that tagged sequences and sets are still parsed as instances of ASN1Data. Find further details on tagged values there.

Example - constructing a SEQUENCE

int = OpenSSL::ASN1::Integer.new(1)
str = OpenSSL::ASN1::PrintableString.new('abc')
sequence = OpenSSL::ASN1::Sequence.new( [ int, str ] )

Example - constructing a SET

int = OpenSSL::ASN1::Integer.new(1)
str = OpenSSL::ASN1::PrintableString.new('abc')
set = OpenSSL::ASN1::Set.new( [ int, str ] )

Infinite length primitive values

The only case where Constructive is used directly is for infinite length encodings of primitive values. These encodings are always constructed, with the contents of the value Array being either UNIVERSAL non-infinite length partial encodings of the actual value or again constructive encodings with infinite length (i.e. infinite length primitive encodings may be constructed recursively with another infinite length value within an already infinite length value). Each partial encoding must be of the same UNIVERSAL type as the overall encoding. The value of the overall encoding consists of the concatenation of each partial encoding taken in sequence. The value array of the outer infinite length value must end with a OpenSSL::ASN1::EndOfContent instance.

Please note that it is not possible to encode Constructive without the infinite_length attribute being set to true, use OpenSSL::ASN1::Sequence or OpenSSL::ASN1::Set in these cases instead.

Example - Infinite length OCTET STRING

partial1 = OpenSSL::ASN1::OctetString.new("\x01")
partial2 = OpenSSL::ASN1::OctetString.new("\x02")
inf_octets = OpenSSL::ASN1::Constructive.new( [ partial1,
                                                partial2,
                                                OpenSSL::ASN1::EndOfContent.new ],
                                              OpenSSL::ASN1::OCTET_STRING,
                                              nil,
                                              :UNIVERSAL )
# The real value of inf_octets is "\x01\x02", i.e. the concatenation
# of partial1 and partial2
inf_octets.infinite_length = true
der = inf_octets.to_der
asn1 = OpenSSL::ASN1.decode(der)
puts asn1.infinite_length # => true

In Files

  • ext/openssl/ossl_asn1.c

Parent

OpenSSL::ASN1::ASN1Data

Included Modules

  • Enumerable

Attributes

tagging[RW]

May be used as a hint for encoding a value either implicitly or explicitly by setting it either to :IMPLICIT or to :EXPLICIT. tagging is not set when a ASN.1 structure is parsed using OpenSSL::ASN1.decode.

Public Class Methods

OpenSSL::ASN1::Primitive.new( value [, tag, tagging, tag_class ]) → Primitive click to toggle source

value: is mandatory.

tag: optional, may be specified for tagged values. If no tag is specified, the UNIVERSAL tag corresponding to the Primitive sub-class is used by default.

tagging: may be used as an encoding hint to encode a value either explicitly or implicitly, see ASN1 for possible values.

tag_class: if tag and tagging are nil then this is set to :UNIVERSAL by default. If either tag or tagging are set then :CONTEXT_SPECIFIC is used as the default. For possible values please cf. ASN1.

Example

int = OpenSSL::ASN1::Integer.new(42)
zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :IMPLICIT)
private_explicit_zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :EXPLICIT, :PRIVATE)
static VALUE
ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE value, tag, tagging, tag_class;

    rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class);
    if(argc > 1){
        if(NIL_P(tag))
            ossl_raise(eASN1Error, "must specify tag number");
        if(!NIL_P(tagging) && !SYMBOL_P(tagging))
            ossl_raise(eASN1Error, "invalid tagging method");
        if(NIL_P(tag_class)) {
            if (NIL_P(tagging))
                tag_class = ID2SYM(sUNIVERSAL);
            else
                tag_class = ID2SYM(sCONTEXT_SPECIFIC);
        }
        if(!SYMBOL_P(tag_class))
            ossl_raise(eASN1Error, "invalid tag class");
        if(!NIL_P(tagging) && SYM2ID(tagging) == sIMPLICIT && NUM2INT(tag) > 31)
            ossl_raise(eASN1Error, "tag number for Universal too large");
    }
    else{
        tag = INT2NUM(ossl_asn1_default_tag(self));
        tagging = Qnil;
        tag_class = ID2SYM(sUNIVERSAL);
    }
    ossl_asn1_set_tag(self, tag);
    ossl_asn1_set_value(self, value);
    ossl_asn1_set_tagging(self, tagging);
    ossl_asn1_set_tag_class(self, tag_class);
    ossl_asn1_set_infinite_length(self, Qfalse);

    return self;
}

Public Instance Methods

each { |asn1| block } → asn1_ary click to toggle source

Calls block once for each element in self, passing that element as parameter asn1. If no block is given, an enumerator is returned instead.

Example

asn1_ary.each do |asn1|
  puts asn1
end

static VALUE
ossl_asn1cons_each(VALUE self)
{
    rb_ary_each(ossl_asn1_get_value(self));
    return self;
}
to_der → DER-encoded String click to toggle source

See OpenSSL::ASN1::ASN1Data#to_der for details.

static VALUE
ossl_asn1cons_to_der(VALUE self)
{
    int tag, tn, tc, explicit, constructed = 1;
    int found_prim = 0, seq_len;
    long length;
    unsigned char *p;
    VALUE value, str, inf_length;

    tn = NUM2INT(ossl_asn1_get_tag(self));
    tc = ossl_asn1_tag_class(self);
    inf_length = ossl_asn1_get_infinite_length(self);
    if (inf_length == Qtrue) {
        VALUE ary, example;
        constructed = 2;
        if (CLASS_OF(self) == cASN1Sequence ||
            CLASS_OF(self) == cASN1Set) {
            tag = ossl_asn1_default_tag(self);
        }
        else { /* must be a constructive encoding of a primitive value */
            ary = ossl_asn1_get_value(self);
            if (!rb_obj_is_kind_of(ary, rb_cArray))
                ossl_raise(eASN1Error, "Constructive value must be an Array");
            /* Recursively descend until a primitive value is found.
            The overall value of the entire constructed encoding
            is of the type of the first primitive encoding to be
            found. */
            while (!found_prim){
                example = rb_ary_entry(ary, 0);
                if (rb_obj_is_kind_of(example, cASN1Primitive)){
                    found_prim = 1;
                }
                else {
                    /* example is another ASN1Constructive */
                    if (!rb_obj_is_kind_of(example, cASN1Constructive)){
                        ossl_raise(eASN1Error, "invalid constructed encoding");
                        return Qnil; /* dummy */
                    }
                    ary = ossl_asn1_get_value(example);
                }
            }
            tag = ossl_asn1_default_tag(example);
        }
    }
    else {
        if (CLASS_OF(self) == cASN1Constructive)
            ossl_raise(eASN1Error, "Constructive shall only be used with infinite length");
        tag = ossl_asn1_default_tag(self);
    }
    explicit = ossl_asn1_is_explicit(self);
    value = join_der(ossl_asn1_get_value(self));

    seq_len = ossl_asn1_object_size(constructed, RSTRING_LENINT(value), tag);
    length = ossl_asn1_object_size(constructed, seq_len, tn);
    str = rb_str_new(0, length);
    p = (unsigned char *)RSTRING_PTR(str);
    if(tc == V_ASN1_UNIVERSAL)
        ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
    else{
        if(explicit){
            ossl_asn1_put_object(&p, constructed, seq_len, tn, tc);
            ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tag, V_ASN1_UNIVERSAL);
        }
        else{
            ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
        }
    }
    memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
    p += RSTRING_LEN(value);

    /* In this case we need an additional EOC (one for the explicit part and
     * one for the Constructive itself. The EOC for the Constructive is
     * supplied by the user, but that for the "explicit wrapper" must be
     * added here.
     */
    if (explicit && inf_length == Qtrue) {
        ASN1_put_eoc(&p);
    }
    ossl_str_adjust(str, p);

    return str;
}


class OpenSSL::ASN1::ObjectId - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::ASN1::ObjectId

Document-module: OpenSSL::ASN1

Abstract Syntax Notation One (or ASN.1) is a notation syntax to describe data structures and is defined in ITU-T X.680. ASN.1 itself does not mandate any encoding or parsing rules, but usually ASN.1 data structures are encoded using the Distinguished Encoding Rules (DER) or less often the Basic Encoding Rules (BER) described in ITU-T X.690. DER and BER encodings are binary Tag-Length-Value (TLV) encodings that are quite concise compared to other popular data description formats such as XML, JSON etc. ASN.1 data structures are very common in cryptographic applications, e.g. X.509 public key certificates or certificate revocation lists (CRLs) are all defined in ASN.1 and DER-encoded. ASN.1, DER and BER are the building blocks of applied cryptography. The ASN1 module provides the necessary classes that allow generation of ASN.1 data structures and the methods to encode them using a DER encoding. The decode method allows parsing arbitrary BER-/DER-encoded data to a Ruby object that can then be modified and re-encoded at will.

ASN.1 class hierarchy

The base class representing ASN.1 structures is ASN1Data. ASN1Data offers attributes to read and set the tag, the tag_class and finally the value of a particular ASN.1 item. Upon parsing, any tagged values (implicit or explicit) will be represented by ASN1Data instances because their “real type” can only be determined using out-of-band information from the ASN.1 type declaration. Since this information is normally known when encoding a type, all sub-classes of ASN1Data offer an additional attribute tagging that allows to encode a value implicitly (:IMPLICIT) or explicitly (:EXPLICIT).

Constructive

Constructive is, as its name implies, the base class for all constructed encodings, i.e. those that consist of several values, opposed to “primitive” encodings with just one single value. Primitive values that are encoded with “infinite length” are typically constructed (their values come in multiple chunks) and are therefore represented by instances of Constructive. The value of an Constructive is always an Array.

ASN1::Set and ASN1::Sequence

The most common constructive encodings are SETs and SEQUENCEs, which is why there are two sub-classes of Constructive representing each of them.

Primitive

This is the super class of all primitive values. Primitive itself is not used when parsing ASN.1 data, all values are either instances of a corresponding sub-class of Primitive or they are instances of ASN1Data if the value was tagged implicitly or explicitly. Please cf. Primitive documentation for details on sub-classes and their respective mappings of ASN.1 data types to Ruby objects.

Possible values for tagging

When constructing an ASN1Data object the ASN.1 type definition may require certain elements to be either implicitly or explicitly tagged. This can be achieved by setting the tagging attribute manually for sub-classes of ASN1Data. Use the symbol :IMPLICIT for implicit tagging and :EXPLICIT if the element requires explicit tagging.

Possible values for tag_class

It is possible to create arbitrary ASN1Data objects that also support a PRIVATE or APPLICATION tag class. Possible values for the tag_class attribute are:

  • :UNIVERSAL (the default for untagged values)

  • :CONTEXT_SPECIFIC (the default for tagged values)

  • :APPLICATION

  • :PRIVATE

Tag constants

There is a constant defined for each universal tag:

  • OpenSSL::ASN1::EOC (0)

  • OpenSSL::ASN1::BOOLEAN (1)

  • OpenSSL::ASN1::INTEGER (2)

  • OpenSSL::ASN1::BIT_STRING (3)

  • OpenSSL::ASN1::OCTET_STRING (4)

  • OpenSSL::ASN1::NULL (5)

  • OpenSSL::ASN1::OBJECT (6)

  • OpenSSL::ASN1::ENUMERATED (10)

  • OpenSSL::ASN1::UTF8STRING (12)

  • OpenSSL::ASN1::SEQUENCE (16)

  • OpenSSL::ASN1::SET (17)

  • OpenSSL::ASN1::NUMERICSTRING (18)

  • OpenSSL::ASN1::PRINTABLESTRING (19)

  • OpenSSL::ASN1::T61STRING (20)

  • OpenSSL::ASN1::VIDEOTEXSTRING (21)

  • OpenSSL::ASN1::IA5STRING (22)

  • OpenSSL::ASN1::UTCTIME (23)

  • OpenSSL::ASN1::GENERALIZEDTIME (24)

  • OpenSSL::ASN1::GRAPHICSTRING (25)

  • OpenSSL::ASN1::ISO64STRING (26)

  • OpenSSL::ASN1::GENERALSTRING (27)

  • OpenSSL::ASN1::UNIVERSALSTRING (28)

  • OpenSSL::ASN1::BMPSTRING (30)

UNIVERSAL_TAG_NAME constant

An Array that stores the name of a given tag number. These names are the same as the name of the tag constant that is additionally defined, e.g. UNIVERSAL_TAG_NAME = “INTEGER” and OpenSSL::ASN1::INTEGER = 2.

Example usage

Decoding and viewing a DER-encoded file

require 'openssl'
require 'pp'
der = File.binread('data.der')
asn1 = OpenSSL::ASN1.decode(der)
pp der

Creating an ASN.1 structure and DER-encoding it

require 'openssl'
version = OpenSSL::ASN1::Integer.new(1)
# Explicitly 0-tagged implies context-specific tag class
serial = OpenSSL::ASN1::Integer.new(12345, 0, :EXPLICIT, :CONTEXT_SPECIFIC)
name = OpenSSL::ASN1::PrintableString.new('Data 1')
sequence = OpenSSL::ASN1::Sequence.new( [ version, serial, name ] )
der = sequence.to_der

In Files

  • ext/openssl/ossl_asn1.c

Parent

OpenSSL::ASN1::Primitive

Public Class Methods

register(p1, p2, p3) click to toggle source
static VALUE
ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln)
{
    StringValue(oid);
    StringValue(sn);
    StringValue(ln);

    if(!OBJ_create(RSTRING_PTR(oid), RSTRING_PTR(sn), RSTRING_PTR(ln)))
        ossl_raise(eASN1Error, NULL);

    return Qtrue;
}

Public Instance Methods

ln() click to toggle source
static VALUE
ossl_asn1obj_get_ln(VALUE self)
{
    VALUE val, ret = Qnil;
    int nid;

    val = ossl_asn1_get_value(self);
    if ((nid = OBJ_txt2nid(StringValuePtr(val))) != NID_undef)
        ret = rb_str_new2(OBJ_nid2ln(nid));

    return ret;
}
Also aliased as: long_name
long_name() click to toggle source
Alias for: ln
oid() click to toggle source
static VALUE
ossl_asn1obj_get_oid(VALUE self)
{
    VALUE val;
    ASN1_OBJECT *a1obj;
    char buf[128];

    val = ossl_asn1_get_value(self);
    a1obj = obj_to_asn1obj(val);
    OBJ_obj2txt(buf, sizeof(buf), a1obj, 1);
    ASN1_OBJECT_free(a1obj);

    return rb_str_new2(buf);
}
short_name() click to toggle source
Alias for: sn
sn() click to toggle source
static VALUE
ossl_asn1obj_get_sn(VALUE self)
{
    VALUE val, ret = Qnil;
    int nid;

    val = ossl_asn1_get_value(self);
    if ((nid = OBJ_txt2nid(StringValuePtr(val))) != NID_undef)
        ret = rb_str_new2(OBJ_nid2sn(nid));

    return ret;
}
Also aliased as: short_name


class OpenSSL::ASN1::Primitive - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::ASN1::Primitive

The parent class for all primitive encodings. Attributes are the same as for ASN1Data, with the addition of tagging. Primitive values can never be infinite length encodings, thus it is not possible to set the infinite_length attribute for Primitive and its sub-classes.

Primitive sub-classes and their mapping to Ruby classes

  • OpenSSL::ASN1::EndOfContent <=> value is always nil

  • OpenSSL::ASN1::Boolean <=> value is a Boolean

  • OpenSSL::ASN1::Integer <=> value is a Number

  • OpenSSL::ASN1::BitString <=> value is a String

  • OpenSSL::ASN1::OctetString <=> value is a String

  • OpenSSL::ASN1::Null <=> value is always nil

  • OpenSSL::ASN1::Object <=> value is a String

  • OpenSSL::ASN1::Enumerated <=> value is a Number

  • OpenSSL::ASN1::UTF8String <=> value is a String

  • OpenSSL::ASN1::NumericString <=> value is a String

  • OpenSSL::ASN1::PrintableString <=> value is a String

  • OpenSSL::ASN1::T61String <=> value is a String

  • OpenSSL::ASN1::VideotexString <=> value is a String

  • OpenSSL::ASN1::IA5String <=> value is a String

  • OpenSSL::ASN1::UTCTime <=> value is a Time

  • OpenSSL::ASN1::GeneralizedTime <=> value is a Time

  • OpenSSL::ASN1::GraphicString <=> value is a String

  • OpenSSL::ASN1::ISO64String <=> value is a String

  • OpenSSL::ASN1::GeneralString <=> value is a String

  • OpenSSL::ASN1::UniversalString <=> value is a String

  • OpenSSL::ASN1::BMPString <=> value is a String

OpenSSL::ASN1::BitString

Additional attributes

unused_bits: if the underlying BIT STRING's length is a multiple of 8 then unused_bits is 0. Otherwise unused_bits indicates the number of bits that are to be ignored in the final octet of the BitString's value.

OpenSSL::ASN1::ObjectId

Additional attributes

  • sn: the short name as defined in <openssl/objects.h>.

  • ln: the long name as defined in <openssl/objects.h>.

  • oid: the object identifier as a String, e.g. “1.2.3.4.5”

  • short_name: alias for sn.

  • long_name: alias for ln.

Examples

With the Exception of OpenSSL::ASN1::EndOfContent, each Primitive class constructor takes at least one parameter, the value.

Creating EndOfContent

eoc = OpenSSL::ASN1::EndOfContent.new

Creating any other Primitive

prim = <class>.new(value) # <class> being one of the sub-classes except EndOfContent
prim_zero_tagged_implicit = <class>.new(value, 0, :IMPLICIT)
prim_zero_tagged_explicit = <class>.new(value, 0, :EXPLICIT)

In Files

  • ext/openssl/ossl_asn1.c

Parent

OpenSSL::ASN1::ASN1Data

Attributes

tagging[RW]

May be used as a hint for encoding a value either implicitly or explicitly by setting it either to :IMPLICIT or to :EXPLICIT. tagging is not set when a ASN.1 structure is parsed using OpenSSL::ASN1.decode.

Public Class Methods

OpenSSL::ASN1::Primitive.new( value [, tag, tagging, tag_class ]) → Primitive click to toggle source

value: is mandatory.

tag: optional, may be specified for tagged values. If no tag is specified, the UNIVERSAL tag corresponding to the Primitive sub-class is used by default.

tagging: may be used as an encoding hint to encode a value either explicitly or implicitly, see ASN1 for possible values.

tag_class: if tag and tagging are nil then this is set to :UNIVERSAL by default. If either tag or tagging are set then :CONTEXT_SPECIFIC is used as the default. For possible values please cf. ASN1.

Example

int = OpenSSL::ASN1::Integer.new(42)
zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :IMPLICIT)
private_explicit_zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :EXPLICIT, :PRIVATE)
static VALUE
ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE value, tag, tagging, tag_class;

    rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class);
    if(argc > 1){
        if(NIL_P(tag))
            ossl_raise(eASN1Error, "must specify tag number");
        if(!NIL_P(tagging) && !SYMBOL_P(tagging))
            ossl_raise(eASN1Error, "invalid tagging method");
        if(NIL_P(tag_class)) {
            if (NIL_P(tagging))
                tag_class = ID2SYM(sUNIVERSAL);
            else
                tag_class = ID2SYM(sCONTEXT_SPECIFIC);
        }
        if(!SYMBOL_P(tag_class))
            ossl_raise(eASN1Error, "invalid tag class");
        if(!NIL_P(tagging) && SYM2ID(tagging) == sIMPLICIT && NUM2INT(tag) > 31)
            ossl_raise(eASN1Error, "tag number for Universal too large");
    }
    else{
        tag = INT2NUM(ossl_asn1_default_tag(self));
        tagging = Qnil;
        tag_class = ID2SYM(sUNIVERSAL);
    }
    ossl_asn1_set_tag(self, tag);
    ossl_asn1_set_value(self, value);
    ossl_asn1_set_tagging(self, tagging);
    ossl_asn1_set_tag_class(self, tag_class);
    ossl_asn1_set_infinite_length(self, Qfalse);

    return self;
}

Public Instance Methods

to_der → DER-encoded String click to toggle source

See OpenSSL::ASN1::ASN1Data#to_der for details. *

static VALUE
ossl_asn1prim_to_der(VALUE self)
{
    ASN1_TYPE *asn1;
    int tn, tc, explicit;
    long len, reallen;
    unsigned char *buf, *p;
    VALUE str;

    tn = NUM2INT(ossl_asn1_get_tag(self));
    tc = ossl_asn1_tag_class(self);
    explicit = ossl_asn1_is_explicit(self);
    asn1 = ossl_asn1_get_asn1type(self);

    len = ossl_asn1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn);
    if(!(buf = OPENSSL_malloc(len))){
        ossl_ASN1_TYPE_free(asn1);
        ossl_raise(eASN1Error, "cannot alloc buffer");
    }
    p = buf;
    if (tc == V_ASN1_UNIVERSAL) {
        ossl_i2d_ASN1_TYPE(asn1, &p);
    } else if (explicit) {
        ossl_asn1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc);
        ossl_i2d_ASN1_TYPE(asn1, &p);
    } else {
        ossl_i2d_ASN1_TYPE(asn1, &p);
        *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);
    }
    ossl_ASN1_TYPE_free(asn1);
    reallen = p - buf;
    assert(reallen <= len);
    str = ossl_buf2str((char *)buf, rb_long2int(reallen)); /* buf will be free in ossl_buf2str */

    return str;
}


class OpenSSL::BN - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::BN

In Files

  • ext/openssl/lib/openssl/bn.rb
  • ext/openssl/ossl.c

Parent

Object

Included Modules

  • Comparable

Public Class Methods

generate_prime(bits, [, safe [, add [, rem]]]) → bn click to toggle source

Parameters

  • bits - integer

  • safe - boolean

  • add - BN

  • rem - BN

static VALUE
ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
{
    BIGNUM *add = NULL, *rem = NULL, *result;
    int safe = 1, num;
    VALUE vnum, vsafe, vadd, vrem, obj;

    rb_scan_args(argc, argv, "13", &vnum, &vsafe, &vadd, &vrem);

    num = NUM2INT(vnum);

    if (vsafe == Qfalse) {
        safe = 0;
    }
    if (!NIL_P(vadd)) {
        add = GetBNPtr(vadd);
        rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem);
    }
    if (!(result = BN_new())) {
        ossl_raise(eBNError, NULL);
    }
    if (!BN_generate_prime(result, num, safe, add, rem, NULL, NULL)) {
        BN_free(result);
        ossl_raise(eBNError, NULL);
    }
    WrapBN(klass, obj, result);

    return obj;
}
new → aBN click to toggle source
new(bn) → aBN
new(string) → aBN
new(string, 0 | 2 | 10 | 16) → aBN
static VALUE
ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
{
    BIGNUM *bn;
    VALUE str, bs;
    int base = 10;

    if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
        base = NUM2INT(bs);
    }

    if (RTEST(rb_obj_is_kind_of(str, cBN))) {
        BIGNUM *other;

        GetBN(self, bn);
        GetBN(str, other); /* Safe - we checked kind_of? above */
        if (!BN_copy(bn, other)) {
            ossl_raise(eBNError, NULL);
        }
        return self;
    }

    StringValue(str);
    GetBN(self, bn);
    switch (base) {
    case 0:
        if (!BN_mpi2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) {
            ossl_raise(eBNError, NULL);
        }
        break;
    case 2:
        if (!BN_bin2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) {
            ossl_raise(eBNError, NULL);
        }
        break;
    case 10:
        if (!BN_dec2bn(&bn, RSTRING_PTR(str))) {
            ossl_raise(eBNError, NULL);
        }
        break;
    case 16:
        if (!BN_hex2bn(&bn, RSTRING_PTR(str))) {
            ossl_raise(eBNError, NULL);
        }
        break;
    default:
        ossl_raise(rb_eArgError, "invalid radix %d", base);
    }
    return self;
}

Public Instance Methods

bn1 / bn2 → [result, remainder] click to toggle source
static VALUE
ossl_bn_div(VALUE self, VALUE other)
{
    BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2;
    VALUE obj1, obj2;

    GetBN(self, bn1);

    if (!(r1 = BN_new())) {
        ossl_raise(eBNError, NULL);
    }
    if (!(r2 = BN_new())) {
        BN_free(r1);
        ossl_raise(eBNError, NULL);
    }
    if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) {
        BN_free(r1);
        BN_free(r2);
        ossl_raise(eBNError, NULL);
    }
    WrapBN(CLASS_OF(self), obj1, r1);
    WrapBN(CLASS_OF(self), obj2, r2);

    return rb_ary_new3(2, obj1, obj2);
}
==(p1) click to toggle source
Alias for: eql?
===(p1) click to toggle source
Alias for: eql?
bit_set?(bit) → true | false click to toggle source
static VALUE
ossl_bn_is_bit_set(VALUE self, VALUE bit)
{
    int b;
    BIGNUM *bn;

    b = NUM2INT(bit);
    GetBN(self, bn);
    if (BN_is_bit_set(bn, b)) {
        return Qtrue;
    }
    return Qfalse;
}
coerce(p1) click to toggle source
static VALUE
ossl_bn_coerce(VALUE self, VALUE other)
{
    switch(TYPE(other)) {
    case T_STRING:
        self = ossl_bn_to_s(0, NULL, self);
        break;
    case T_FIXNUM:
    case T_BIGNUM:
        self = ossl_bn_to_i(self);
        break;
    default:
        if (!RTEST(rb_obj_is_kind_of(other, cBN))) {
            ossl_raise(rb_eTypeError, "Don't know how to coerce");
        }
    }
    return rb_assoc_new(other, self);
}
copy(p1) click to toggle source
static VALUE
ossl_bn_copy(VALUE self, VALUE other)
{
    BIGNUM *bn1, *bn2;

    rb_check_frozen(self);

    if (self == other) return self;

    GetBN(self, bn1);
    bn2 = GetBNPtr(other);

    if (!BN_copy(bn1, bn2)) {
        ossl_raise(eBNError, NULL);
    }
    return self;
}
eql?(p1) click to toggle source
static VALUE
ossl_bn_eql(VALUE self, VALUE other)
{
    if (ossl_bn_cmp(self, other) == INT2FIX(0)) {
        return Qtrue;
    }
    return Qfalse;
}
Also aliased as: ==, ===
prime? → true | false click to toggle source
prime?(checks) → true | false

Parameters

  • checks - integer

static VALUE
ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
{
    BIGNUM *bn;
    VALUE vchecks;
    int checks = BN_prime_checks;

    if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
        checks = NUM2INT(vchecks);
    }
    GetBN(self, bn);
    switch (BN_is_prime(bn, checks, NULL, ossl_bn_ctx, NULL)) {
    case 1:
        return Qtrue;
    case 0:
        return Qfalse;
    default:
        ossl_raise(eBNError, NULL);
    }
    /* not reachable */
    return Qnil;
}
prime_fasttest? → true | false click to toggle source
prime_fasttest?(checks) → true | false
prime_fasttest?(checks, trial_div) → true | false

Parameters

  • checks - integer

  • trial_div - boolean

static VALUE
ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
{
    BIGNUM *bn;
    VALUE vchecks, vtrivdiv;
    int checks = BN_prime_checks, do_trial_division = 1;

    rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);

    if (!NIL_P(vchecks)) {
        checks = NUM2INT(vchecks);
    }
    GetBN(self, bn);
    /* handle true/false */
    if (vtrivdiv == Qfalse) {
        do_trial_division = 0;
    }
    switch (BN_is_prime_fasttest(bn, checks, NULL, ossl_bn_ctx, NULL, do_trial_division)) {
    case 1:
        return Qtrue;
    case 0:
        return Qfalse;
    default:
        ossl_raise(eBNError, NULL);
    }
    /* not reachable */
    return Qnil;
}
to_bn() click to toggle source
static VALUE
ossl_bn_to_bn(VALUE self)
{
    return self;
}
to_i → integer click to toggle source
static VALUE
ossl_bn_to_i(VALUE self)
{
    BIGNUM *bn;
    char *txt;
    VALUE num;

    GetBN(self, bn);

    if (!(txt = BN_bn2dec(bn))) {
        ossl_raise(eBNError, NULL);
    }
    num = rb_cstr_to_inum(txt, 10, Qtrue);
    OPENSSL_free(txt);

    return num;
}
Also aliased as: to_int
to_int() click to toggle source
Alias for: to_i
to_s → string click to toggle source
to_s(base) → string

Parameters

  • base - integer

    • Valid values:

      • 0 - MPI

      • 2 - binary

      • 10 - the default

      • 16 - hex

static VALUE
ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
{
    BIGNUM *bn;
    VALUE str, bs;
    int base = 10, len;
    char *buf;

    if (rb_scan_args(argc, argv, "01", &bs) == 1) {
        base = NUM2INT(bs);
    }
    GetBN(self, bn);
    switch (base) {
    case 0:
        len = BN_bn2mpi(bn, NULL);
        str = rb_str_new(0, len);
        if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len)
            ossl_raise(eBNError, NULL);
        break;
    case 2:
        len = BN_num_bytes(bn);
        str = rb_str_new(0, len);
        if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len)
            ossl_raise(eBNError, NULL);
        break;
    case 10:
        if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL);
        str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
        break;
    case 16:
        if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL);
        str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
        break;
    default:
        ossl_raise(rb_eArgError, "invalid radix %d", base);
    }

    return str;
}


class OpenSSL::BNError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::BNError

In Files

  • ext/openssl/ossl.c

Parent

eOSSLError


module OpenSSL::Buffering - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::Buffering

OpenSSL IO buffering mix-in module.

This module allows an OpenSSL::SSL::SSLSocket to behave like an IO.

In Files

  • ext/openssl/lib/openssl/buffering.rb

Included Modules

  • Enumerable

Constants

BLOCK_SIZE

Default size to read from or write to the SSLSocket for buffer operations.

Attributes

sync[RW]

The “sync mode” of the SSLSocket.

See IO#sync for full details.

Public Class Methods

new(*args) click to toggle source
# File ext/openssl/lib/openssl/buffering.rb, line 38
def initialize(*args)
  @eof = false
  @rbuffer = ""
  @sync = @io.sync
end

Public Instance Methods

<<(s) click to toggle source

Writes s to the stream. s will be converted to a String using String#to_s.

# File ext/openssl/lib/openssl/buffering.rb, line 383
def << (s)
  do_write(s)
  self
end
close() click to toggle source

Closes the SSLSocket and flushes any unwritten data.

# File ext/openssl/lib/openssl/buffering.rb, line 446
def close
  flush rescue nil
  sysclose
end
each(eol=$/) { |line| ... } click to toggle source

Executes the block for every line in the stream where lines are separated by eol.

See also gets

# File ext/openssl/lib/openssl/buffering.rb, line 221
def each(eol=$/)
  while line = self.gets(eol)
    yield line
  end
end
Also aliased as: each_line
each_byte() { |byte| ... } click to toggle source

Calls the given block once for each byte in the stream.

# File ext/openssl/lib/openssl/buffering.rb, line 262
def each_byte # :yields: byte
  while c = getc
    yield(c.ord)
  end
end
each_line(eol=$/) click to toggle source
Alias for: each
eof() click to toggle source
Alias for: eof?
eof?() click to toggle source

Returns true if the stream is at file which means there is no more data to be read.

# File ext/openssl/lib/openssl/buffering.rb, line 293
def eof?
  fill_rbuff if !@eof && @rbuffer.empty?
  @eof && @rbuffer.empty?
end
Also aliased as: eof
flush() click to toggle source

Flushes buffered data to the SSLSocket.

# File ext/openssl/lib/openssl/buffering.rb, line 434
def flush
  osync = @sync
  @sync = true
  do_write ""
  return self
ensure
  @sync = osync
end
getc() click to toggle source

Reads one character from the stream. Returns nil if called at end of file.

# File ext/openssl/lib/openssl/buffering.rb, line 255
def getc
  read(1)
end
gets(eol=$/, limit=nil) click to toggle source

Reads the next “line+ from the stream. Lines are separated by eol. If limit is provided the result will not be longer than the given number of bytes.

eol may be a String or Regexp.

Unlike IO#gets the line read will not be assigned to +$_+.

Unlike IO#gets the separator must be provided if a limit is provided.

# File ext/openssl/lib/openssl/buffering.rb, line 197
def gets(eol=$/, limit=nil)
  idx = @rbuffer.index(eol)
  until @eof
    break if idx
    fill_rbuff
    idx = @rbuffer.index(eol)
  end
  if eol.is_a?(Regexp)
    size = idx ? idx+$&.size : nil
  else
    size = idx ? idx+eol.size : nil
  end
  if limit and limit >= 0
    size = [size, limit].min
  end
  consume_rbuff(size)
end
print(*args) click to toggle source

Writes args to the stream.

See IO#print for full details.

# File ext/openssl/lib/openssl/buffering.rb, line 413
def print(*args)
  s = ""
  args.each{ |arg| s << arg.to_s }
  do_write(s)
  nil
end
printf(s, *args) click to toggle source

Formats and writes to the stream converting parameters under control of the format string.

See Kernel#sprintf for format string details.

# File ext/openssl/lib/openssl/buffering.rb, line 426
def printf(s, *args)
  do_write(s % args)
  nil
end
puts(*args) click to toggle source

Writes args to the stream along with a record separator.

See IO#puts for full details.

# File ext/openssl/lib/openssl/buffering.rb, line 393
def puts(*args)
  s = ""
  if args.empty?
    s << "\n"
  end
  args.each{|arg|
    s << arg.to_s
    if $/ && /\n\z/ !~ s
      s << "\n"
    end
  }
  do_write(s)
  nil
end
read(size=nil, buf=nil) click to toggle source

Reads size bytes from the stream. If buf is provided it must reference a string which will receive the data.

See IO#read for full details.

# File ext/openssl/lib/openssl/buffering.rb, line 84
def read(size=nil, buf=nil)
  if size == 0
    if buf
      buf.clear
      return buf
    else
      return ""
    end
  end
  until @eof
    break if size && size <= @rbuffer.size
    fill_rbuff
  end
  ret = consume_rbuff(size) || ""
  if buf
    buf.replace(ret)
    ret = buf
  end
  (size && ret.empty?) ? nil : ret
end
read_nonblock(maxlen, buf=nil) click to toggle source

Reads at most maxlen bytes in the non-blocking manner.

When no data can be read without blocking it raises OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable.

IO::WaitReadable means SSL needs to read internally so #read_nonblock should be called again when the underlying IO is readable.

IO::WaitWritable means SSL needs to write internally so #read_nonblock should be called again after the underlying IO is writable.

#read_nonblock needs two rescue clause as follows:

# emulates blocking read (readpartial).
begin
  result = ssl.read_nonblock(maxlen)
rescue IO::WaitReadable
  IO.select([io])
  retry
rescue IO::WaitWritable
  IO.select(nil, [io])
  retry
end

Note that one reason that #read_nonblock writes to the underlying IO is when the peer requests a new TLS/SSL handshake. See openssl the FAQ for more details. www.openssl.org/support/faq.html

# File ext/openssl/lib/openssl/buffering.rb, line 165
def read_nonblock(maxlen, buf=nil)
  if maxlen == 0
    if buf
      buf.clear
      return buf
    else
      return ""
    end
  end
  if @rbuffer.empty?
    return sysread_nonblock(maxlen, buf)
  end
  ret = consume_rbuff(maxlen)
  if buf
    buf.replace(ret)
    ret = buf
  end
  raise EOFError if ret.empty?
  ret
end
readchar() click to toggle source

Reads a one-character string from the stream. Raises an EOFError at end of file.

# File ext/openssl/lib/openssl/buffering.rb, line 272
def readchar
  raise EOFError if eof?
  getc
end
readline(eol=$/) click to toggle source

Reads a line from the stream which is separated by eol.

Raises EOFError if at end of file.

# File ext/openssl/lib/openssl/buffering.rb, line 246
def readline(eol=$/)
  raise EOFError if eof?
  gets(eol)
end
readlines(eol=$/) click to toggle source

Reads lines from the stream which are separated by eol.

See also gets

# File ext/openssl/lib/openssl/buffering.rb, line 233
def readlines(eol=$/)
  ary = []
  while line = self.gets(eol)
    ary << line
  end
  ary
end
readpartial(maxlen, buf=nil) click to toggle source

Reads at most maxlen bytes from the stream. If buf is provided it must reference a string which will receive the data.

See IO#readpartial for full details.

# File ext/openssl/lib/openssl/buffering.rb, line 111
def readpartial(maxlen, buf=nil)
  if maxlen == 0
    if buf
      buf.clear
      return buf
    else
      return ""
    end
  end
  if @rbuffer.empty?
    begin
      return sysread(maxlen, buf)
    rescue Errno::EAGAIN
      retry
    end
  end
  ret = consume_rbuff(maxlen)
  if buf
    buf.replace(ret)
    ret = buf
  end
  raise EOFError if ret.empty?
  ret
end
ungetc(c) click to toggle source

Pushes character c back onto the stream such that a subsequent buffered character read will return it.

Unlike IO#getc multiple bytes may be pushed back onto the stream.

Has no effect on unbuffered reads (such as sysread).

# File ext/openssl/lib/openssl/buffering.rb, line 285
def ungetc(c)
  @rbuffer[0,0] = c.chr
end
write(s) click to toggle source

Writes s to the stream. If the argument is not a string it will be converted using String#to_s. Returns the number of bytes written.

# File ext/openssl/lib/openssl/buffering.rb, line 336
def write(s)
  do_write(s)
  s.bytesize
end
write_nonblock(s) click to toggle source

Writes str in the non-blocking manner.

If there is buffered data, it is flushed first. This may block.

#write_nonblock returns number of bytes written to the SSL connection.

When no data can be written without blocking it raises OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable.

IO::WaitReadable means SSL needs to read internally so #write_nonblock should be called again after the underlying IO is readable.

IO::WaitWritable means SSL needs to write internally so #write_nonblock should be called again after underlying IO is writable.

So #write_nonblock needs two rescue clause as follows.

# emulates blocking write.
begin
  result = ssl.write_nonblock(str)
rescue IO::WaitReadable
  IO.select([io])
  retry
rescue IO::WaitWritable
  IO.select(nil, [io])
  retry
end

Note that one reason that #write_nonblock reads from the underlying IO is when the peer requests a new TLS/SSL handshake. See the openssl FAQ for more details. www.openssl.org/support/faq.html

# File ext/openssl/lib/openssl/buffering.rb, line 374
def write_nonblock(s)
  flush
  syswrite_nonblock(s)
end


class OpenSSL::Cipher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Cipher

Provides symmetric algorithms for encryption and decryption. The algorithms that are available depend on the particular version of OpenSSL that is installed.

Listing all supported algorithms

A list of supported algorithms can be obtained by

puts OpenSSL::Cipher.ciphers

Instantiating a Cipher

There are several ways to create a Cipher instance. Generally, a Cipher algorithm is categorized by its name, the key length in bits and the cipher mode to be used. The most generic way to create a Cipher is the following

cipher = OpenSSL::Cipher.new('<name>-<key length>-<mode>')

That is, a string consisting of the hyphenated concatenation of the individual components name, key length and mode. Either all uppercase or all lowercase strings may be used, for example:

cipher = OpenSSL::Cipher.new('AES-128-CBC')

For each algorithm supported, there is a class defined under the Cipher class that goes by the name of the cipher, e.g. to obtain an instance of AES, you could also use

# these are equivalent
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher = OpenSSL::Cipher::AES.new(128, 'CBC')
cipher = OpenSSL::Cipher::AES.new('128-CBC')

Finally, due to its wide-spread use, there are also extra classes defined for the different key sizes of AES

cipher = OpenSSL::Cipher::AES128.new(:CBC)
cipher = OpenSSL::Cipher::AES192.new(:CBC)
cipher = OpenSSL::Cipher::AES256.new(:CBC)

Choosing either encryption or decryption mode

Encryption and decryption are often very similar operations for symmetric algorithms, this is reflected by not having to choose different classes for either operation, both can be done using the same class. Still, after obtaining a Cipher instance, we need to tell the instance what it is that we intend to do with it, so we need to call either

cipher.encrypt

or

cipher.decrypt

on the Cipher instance. This should be the first call after creating the instance, otherwise configuration that has already been set could get lost in the process.

Choosing a key

Symmetric encryption requires a key that is the same for the encrypting and for the decrypting party and after initial key establishment should be kept as private information. There are a lot of ways to create insecure keys, the most notable is to simply take a password as the key without processing the password further. A simple and secure way to create a key for a particular Cipher is

cipher = OpenSSL::AES256.new(:CFB)
cipher.encrypt
key = cipher.random_key # also sets the generated key on the Cipher

If you absolutely need to use passwords as encryption keys, you should use Password-Based Key Derivation Function 2 (PBKDF2) by generating the key with the help of the functionality provided by OpenSSL::PKCS5.pbkdf2_hmac_sha1 or OpenSSL::PKCS5.pbkdf2_hmac.

Although there is #pkcs5_keyivgen, its use is deprecated and it should only be used in legacy applications because it does not use the newer PKCS#5 v2 algorithms.

Choosing an IV

The cipher modes CBC, CFB, OFB and CTR all need an “initialization vector”, or short, IV. ECB mode is the only mode that does not require an IV, but there is almost no legitimate use case for this mode because of the fact that it does not sufficiently hide plaintext patterns. Therefore

You should never use ECB mode unless you are absolutely sure that you absolutely need it

Because of this, you will end up with a mode that explicitly requires an IV in any case. Note that for backwards compatibility reasons, setting an IV is not explicitly mandated by the Cipher API. If not set, OpenSSL itself defaults to an all-zeroes IV (“\0”, not the character). Although the IV can be seen as public information, i.e. it may be transmitted in public once generated, it should still stay unpredictable to prevent certain kinds of attacks. Therefore, ideally

Always create a secure random IV for every encryption of your Cipher

A new, random IV should be created for every encryption of data. Think of the IV as a nonce (number used once) - it's public but random and unpredictable. A secure random IV can be created as follows

cipher = ...
cipher.encrypt
key = cipher.random_key
iv = cipher.random_iv # also sets the generated IV on the Cipher

Although the key is generally a random value, too, it is a bad choice
as an IV. There are elaborate ways how an attacker can take advantage
of such an IV. As a general rule of thumb, exposing the key directly
or indirectly should be avoided at all cost and exceptions only be
made with good reason.

Calling #final

ECB (which should not be used) and CBC are both block-based modes. This means that unlike for the other streaming-based modes, they operate on fixed-size blocks of data, and therefore they require a “finalization” step to produce or correctly decrypt the last block of data by appropriately handling some form of padding. Therefore it is essential to add the output of #final to your encryption/decryption buffer or you will end up with decryption errors or truncated data.

Although this is not really necessary for streaming-mode ciphers, it is still recommended to apply the same pattern of adding the output of #final there as well - it also enables you to switch between modes more easily in the future.

Encrypting and decrypting some data

data = "Very, very confidential data"

cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.encrypt
key = cipher.random_key
iv = cipher.random_iv

encrypted = cipher.update(data) + cipher.final
...
decipher = OpenSSL::Cipher::AES.new(128, :CBC)
decipher.decrypt
decipher.key = key
decipher.iv = iv

plain = decipher.update(encrypted) + decipher.final

puts data == plain #=> true

Authenticated Encryption and Associated Data (AEAD)

If the OpenSSL version used supports it, an Authenticated Encryption mode (such as GCM or CCM) should always be preferred over any unauthenticated mode. Currently, OpenSSL supports AE only in combination with Associated Data (AEAD) where additional associated data is included in the encryption process to compute a tag at the end of the encryption. This tag will also be used in the decryption process and by verifying its validity, the authenticity of a given ciphertext is established.

This is superior to unauthenticated modes in that it allows to detect if somebody effectively changed the ciphertext after it had been encrypted. This prevents malicious modifications of the ciphertext that could otherwise be exploited to modify ciphertexts in ways beneficial to potential attackers.

If no associated data is needed for encryption and later decryption, the OpenSSL library still requires a value to be set - “” may be used in case none is available. An example using the GCM (Galois Counter Mode):

cipher = OpenSSL::Cipher::AES.new(128, :GCM)
cipher.encrypt
key = cipher.random_key
iv = cipher.random_iv
cipher.auth_data = ""

encrypted = cipher.update(data) + cipher.final
tag = cipher.auth_tag

decipher = OpenSSL::Cipher::AES.new(128, :GCM)
decipher.decrypt
decipher.key = key
decipher.iv = iv
decipher.auth_tag = tag
decipher.auth_data = ""

plain = decipher.update(encrypted) + decipher.final

puts data == plain #=> true

In Files

  • ext/openssl/lib/openssl/cipher.rb
  • ext/openssl/ossl.c

Parent

Object

Public Class Methods

ciphers → array[string...] click to toggle source

Returns the names of all available ciphers in an array.

static VALUE
ossl_s_ciphers(VALUE self)
{
    VALUE ary;

    ary = rb_ary_new();
    OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
                    (void(*)(const OBJ_NAME*,void*))add_cipher_name_to_ary,
                    (void*)ary);

    return ary;
}
new(string) → cipher click to toggle source

The string must contain a valid cipher name like “AES-128-CBC” or “3DES”.

A list of cipher names is available by calling ::ciphers.

static VALUE
ossl_cipher_initialize(VALUE self, VALUE str)
{
    EVP_CIPHER_CTX *ctx;
    const EVP_CIPHER *cipher;
    char *name;
    unsigned char key[EVP_MAX_KEY_LENGTH];

    name = StringValuePtr(str);
    GetCipherInit(self, ctx);
    if (ctx) {
        ossl_raise(rb_eRuntimeError, "Cipher already inititalized!");
    }
    AllocCipher(self, ctx);
    EVP_CIPHER_CTX_init(ctx);
    if (!(cipher = EVP_get_cipherbyname(name))) {
        ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%s)", name);
    }
    /*
     * The EVP which has EVP_CIPH_RAND_KEY flag (such as DES3) allows
     * uninitialized key, but other EVPs (such as AES) does not allow it.
     * Calling EVP_CipherUpdate() without initializing key causes SEGV so we
     * set the data filled with "\0" as the key by default.
     */
    memset(key, 0, EVP_MAX_KEY_LENGTH);
    if (EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, -1) != 1)
        ossl_raise(eCipherError, NULL);

    return self;
}

Public Instance Methods

auth_data = string → string click to toggle source

Sets the cipher's additional authenticated data. This field must be set when using AEAD cipher modes such as GCM or CCM. If no associated data shall be used, this method must still be called with a value of “”. The contents of this field should be non-sensitive data which will be added to the ciphertext to generate the authentication tag which validates the contents of the ciphertext.

The AAD must be set prior to encryption or decryption. In encryption mode, it must be set after calling #encrypt and setting #key= and #iv=. When decrypting, the authenticated data must be set after key, iv and especially after the authentication tag has been set. I.e. set it only after calling #decrypt, #key=, #iv= and #auth_tag= first.

static VALUE
ossl_cipher_set_auth_data(VALUE self, VALUE data)
{
    EVP_CIPHER_CTX *ctx;
    unsigned char *in;
    int in_len;
    int out_len;

    StringValue(data);

    in = (unsigned char *) RSTRING_PTR(data);
    in_len = RSTRING_LENINT(data);

    GetCipher(self, ctx);

    if (!EVP_CipherUpdate(ctx, NULL, &out_len, in, in_len))
        ossl_raise(eCipherError, "couldn't set additional authenticated data");

    return data;
}
auth_tag([ tag_len ] → string click to toggle source

Gets the authentication tag generated by Authenticated Encryption Cipher modes (GCM for example). This tag may be stored along with the ciphertext, then set on the decryption cipher to authenticate the contents of the ciphertext against changes. If the optional integer parameter tag_len is given, the returned tag will be tag_len bytes long. If the parameter is omitted, the maximum length of 16 bytes will be returned. For maximum security, the default of 16 bytes should be chosen.

The tag may only be retrieved after calling #final.

static VALUE
ossl_cipher_get_auth_tag(int argc, VALUE *argv, VALUE self)
{
    VALUE vtag_len;
    EVP_CIPHER_CTX *ctx;
    int nid, tag_len;

    if (rb_scan_args(argc, argv, "01", &vtag_len) == 0) {
        tag_len = 16;
    } else {
        tag_len = NUM2INT(vtag_len);
    }

    GetCipher(self, ctx);
    nid = EVP_CIPHER_CTX_nid(ctx);

    if (ossl_is_gcm(nid)) {
        return ossl_get_gcm_auth_tag(ctx, tag_len);
    } else {
        ossl_raise(eCipherError, "authentication tag not supported by this cipher");
        return Qnil; /* dummy */
    }
}
auth_tag = string → string click to toggle source

Sets the authentication tag to verify the contents of the ciphertext. The tag must be set after calling #decrypt, #key= and #iv=, but before assigning the associated authenticated data using #auth_data= and of course, before decrypting any of the ciphertext. After all decryption is performed, the tag is verified automatically in the call to #final.

static VALUE
ossl_cipher_set_auth_tag(VALUE self, VALUE vtag)
{
    EVP_CIPHER_CTX *ctx;
    int nid;
    unsigned char *tag;
    int tag_len;

    StringValue(vtag);
    tag = (unsigned char *) RSTRING_PTR(vtag);
    tag_len = RSTRING_LENINT(vtag);

    GetCipher(self, ctx);
    nid = EVP_CIPHER_CTX_nid(ctx);

    if (ossl_is_gcm(nid)) {
        ossl_set_gcm_auth_tag(ctx, tag, tag_len);
    } else {
        ossl_raise(eCipherError, "authentication tag not supported by this cipher");
    }

    return vtag;
}
authenticated? → boolean click to toggle source

Indicated whether this Cipher instance uses an Authenticated Encryption mode.

static VALUE
ossl_cipher_is_authenticated(VALUE self)
{
    EVP_CIPHER_CTX *ctx;
    int nid;

    GetCipher(self, ctx);
    nid = EVP_CIPHER_CTX_nid(ctx);

    if (ossl_is_gcm(nid)) {
        return Qtrue;
    } else {
        return Qfalse;
    }
}
decrypt → self click to toggle source

Initializes the Cipher for decryption.

Make sure to call #encrypt or #decrypt before using any of the following methods:

  • key=, iv=, #random_key, #random_iv, #pkcs5_keyivgen

Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 0).

static VALUE
ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self)
{
    return ossl_cipher_init(argc, argv, self, 0);
}
encrypt → self click to toggle source

Initializes the Cipher for encryption.

Make sure to call #encrypt or #decrypt before using any of the following methods:

  • key=, iv=, #random_key, #random_iv, #pkcs5_keyivgen

Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 1).

static VALUE
ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self)
{
    return ossl_cipher_init(argc, argv, self, 1);
}
final → string click to toggle source

Returns the remaining data held in the cipher object. Further calls to #update or #final will return garbage. This call should always be made as the last call of an encryption or decryption operation, after after having fed the entire plaintext or ciphertext to the Cipher instance.

If an authenticated cipher was used, a CipherError is raised if the tag could not be authenticated successfully. Only call this method after setting the authentication tag and passing the entire contents of the ciphertext into the cipher.

static VALUE
ossl_cipher_final(VALUE self)
{
    EVP_CIPHER_CTX *ctx;
    int out_len;
    VALUE str;

    GetCipher(self, ctx);
    str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx));
    if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len))
        ossl_raise(eCipherError, NULL);
    assert(out_len <= RSTRING_LEN(str));
    rb_str_set_len(str, out_len);

    return str;
}
iv = string → string click to toggle source

Sets the cipher IV. Please note that since you should never be using ECB mode, an IV is always explicitly required and should be set prior to encryption. The IV itself can be safely transmitted in public, but it should be unpredictable to prevent certain kinds of attacks. You may use #random_iv to create a secure random IV.

Only call this method after calling #encrypt or #decrypt.

If not explicitly set, the OpenSSL default of an all-zeroes (“\0”) IV is used.

static VALUE
ossl_cipher_set_iv(VALUE self, VALUE iv)
{
    EVP_CIPHER_CTX *ctx;

    StringValue(iv);
    GetCipher(self, ctx);

    if (RSTRING_LEN(iv) < EVP_CIPHER_CTX_iv_length(ctx))
        ossl_raise(eCipherError, "iv length too short");

    if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, (unsigned char *)RSTRING_PTR(iv), -1) != 1)
        ossl_raise(eCipherError, NULL);

    return iv;
}
key = string → string click to toggle source

Sets the cipher key. To generate a key, you should either use a secure random byte string or, if the key is to be derived from a password, you should rely on PBKDF2 functionality provided by OpenSSL::PKCS5. To generate a secure random-based key, #random_key may be used.

Only call this method after calling #encrypt or #decrypt.

static VALUE
ossl_cipher_set_key(VALUE self, VALUE key)
{
    EVP_CIPHER_CTX *ctx;

    StringValue(key);
    GetCipher(self, ctx);

    if (RSTRING_LEN(key) < EVP_CIPHER_CTX_key_length(ctx))
        ossl_raise(eCipherError, "key length too short");

    if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1)
        ossl_raise(eCipherError, NULL);

    return key;
}
key_len = integer → integer click to toggle source

Sets the key length of the cipher. If the cipher is a fixed length cipher then attempting to set the key length to any value other than the fixed value is an error.

Under normal circumstances you do not need to call this method (and probably shouldn't).

See EVP_CIPHER_CTX_set_key_length for further information.

static VALUE
ossl_cipher_set_key_length(VALUE self, VALUE key_length)
{
    int len = NUM2INT(key_length);
    EVP_CIPHER_CTX *ctx;

    GetCipher(self, ctx);
    if (EVP_CIPHER_CTX_set_key_length(ctx, len) != 1)
        ossl_raise(eCipherError, NULL);

    return key_length;
}
name → string click to toggle source

Returns the name of the cipher which may differ slightly from the original name provided.

static VALUE
ossl_cipher_name(VALUE self)
{
    EVP_CIPHER_CTX *ctx;

    GetCipher(self, ctx);

    return rb_str_new2(EVP_CIPHER_name(EVP_CIPHER_CTX_cipher(ctx)));
}
padding = integer → integer click to toggle source

Enables or disables padding. By default encryption operations are padded using standard block padding and the padding is checked and removed when decrypting. If the pad parameter is zero then no padding is performed, the total amount of data encrypted or decrypted must then be a multiple of the block size or an error will occur.

See EVP_CIPHER_CTX_set_padding for further information.

static VALUE
ossl_cipher_set_padding(VALUE self, VALUE padding)
{
    EVP_CIPHER_CTX *ctx;
    int pad = NUM2INT(padding);

    GetCipher(self, ctx);
    if (EVP_CIPHER_CTX_set_padding(ctx, pad) != 1)
        ossl_raise(eCipherError, NULL);
    return padding;
}
pkcs5_keyivgen(pass [, salt [, iterations [, digest]]] ) → nil click to toggle source

Generates and sets the key/IV based on a password.

WARNING: This method is only PKCS5 v1.5 compliant when using RC2, RC4-40, or DES with MD5 or SHA1. Using anything else (like AES) will generate the key/iv using an OpenSSL specific method. This method is deprecated and should no longer be used. Use a PKCS5 v2 key generation method from OpenSSL::PKCS5 instead.

Parameters

salt must be an 8 byte string if provided. iterations is a integer with a default of 2048. digest is a Digest object that defaults to 'MD5'

A minimum of 1000 iterations is recommended.

static VALUE
ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
{
    EVP_CIPHER_CTX *ctx;
    const EVP_MD *digest;
    VALUE vpass, vsalt, viter, vdigest;
    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt = NULL;
    int iter;

    rb_scan_args(argc, argv, "13", &vpass, &vsalt, &viter, &vdigest);
    StringValue(vpass);
    if(!NIL_P(vsalt)){
        StringValue(vsalt);
        if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN)
            ossl_raise(eCipherError, "salt must be an 8-octet string");
        salt = (unsigned char *)RSTRING_PTR(vsalt);
    }
    iter = NIL_P(viter) ? 2048 : NUM2INT(viter);
    digest = NIL_P(vdigest) ? EVP_md5() : GetDigestPtr(vdigest);
    GetCipher(self, ctx);
    EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
                   (unsigned char *)RSTRING_PTR(vpass), RSTRING_LENINT(vpass), iter, key, iv);
    if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1)
        ossl_raise(eCipherError, NULL);
    OPENSSL_cleanse(key, sizeof key);
    OPENSSL_cleanse(iv, sizeof iv);

    return Qnil;
}
random_iv() click to toggle source

Generate, set, and return a random iv. You must call cipher.encrypt or cipher.decrypt before calling this method.

# File ext/openssl/lib/openssl/cipher.rb, line 54
def random_iv
  str = OpenSSL::Random.random_bytes(self.iv_len)
  self.iv = str
  return str
end
random_key() click to toggle source

Generate, set, and return a random key. You must call cipher.encrypt or cipher.decrypt before calling this method.

# File ext/openssl/lib/openssl/cipher.rb, line 46
def random_key
  str = OpenSSL::Random.random_bytes(self.key_len)
  self.key = str
  return str
end
reset → self click to toggle source

Fully resets the internal state of the Cipher. By using this, the same Cipher instance may be used several times for en- or decryption tasks.

Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1).

static VALUE
ossl_cipher_reset(VALUE self)
{
    EVP_CIPHER_CTX *ctx;

    GetCipher(self, ctx);
    if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1) != 1)
        ossl_raise(eCipherError, NULL);

    return self;
}
update(data [, buffer]) → string or buffer click to toggle source

Encrypts data in a streaming fashion. Hand consecutive blocks of data to the update method in order to encrypt it. Returns the encrypted data chunk. When done, the output of #final should be additionally added to the result.

Parameters

data is a nonempty string. buffer is an optional string to store the result.

static VALUE
ossl_cipher_update(int argc, VALUE *argv, VALUE self)
{
    EVP_CIPHER_CTX *ctx;
    unsigned char *in;
    int in_len, out_len;
    VALUE data, str;

    rb_scan_args(argc, argv, "11", &data, &str);

    StringValue(data);
    in = (unsigned char *)RSTRING_PTR(data);
    if ((in_len = RSTRING_LENINT(data)) == 0)
        ossl_raise(rb_eArgError, "data must not be empty");
    GetCipher(self, ctx);
    out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);

    if (NIL_P(str)) {
        str = rb_str_new(0, out_len);
    } else {
        StringValue(str);
        rb_str_resize(str, out_len);
    }

    if (!EVP_CipherUpdate(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len))
        ossl_raise(eCipherError, NULL);
    assert(out_len < RSTRING_LEN(str));
    rb_str_set_len(str, out_len);

    return str;
}


class OpenSSL::Cipher::Cipher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Cipher::Cipher

This class is only provided for backwards compatibility. Use OpenSSL::Cipher in the future.

In Files

  • ext/openssl/lib/openssl/cipher.rb

Parent

OpenSSL::Cipher


class OpenSSL::Cipher::CipherError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Cipher::CipherError

Document-class: OpenSSL::Cipher

Provides symmetric algorithms for encryption and decryption. The
algorithms that are available depend on the particular version
of OpenSSL that is installed.

=== Listing all supported algorithms

A list of supported algorithms can be obtained by

  puts OpenSSL::Cipher.ciphers

=== Instantiating a Cipher

There are several ways to create a Cipher instance. Generally, a
Cipher algorithm is categorized by its name, the key length in bits
and the cipher mode to be used. The most generic way to create a
Cipher is the following

  cipher = OpenSSL::Cipher.new('<name>-<key length>-<mode>')

That is, a string consisting of the hyphenated concatenation of the
individual components name, key length and mode. Either all uppercase
or all lowercase strings may be used, for example:

 cipher = OpenSSL::Cipher.new('AES-128-CBC')

For each algorithm supported, there is a class defined under the
Cipher class that goes by the name of the cipher, e.g. to obtain an
instance of AES, you could also use

  # these are equivalent
  cipher = OpenSSL::Cipher::AES.new(128, :CBC)
  cipher = OpenSSL::Cipher::AES.new(128, 'CBC')
  cipher = OpenSSL::Cipher::AES.new('128-CBC')

Finally, due to its wide-spread use, there are also extra classes
defined for the different key sizes of AES

  cipher = OpenSSL::Cipher::AES128.new(:CBC)
  cipher = OpenSSL::Cipher::AES192.new(:CBC)
  cipher = OpenSSL::Cipher::AES256.new(:CBC)

=== Choosing either encryption or decryption mode

Encryption and decryption are often very similar operations for
symmetric algorithms, this is reflected by not having to choose
different classes for either operation, both can be done using the
same class. Still, after obtaining a Cipher instance, we need to
tell the instance what it is that we intend to do with it, so we
need to call either

  cipher.encrypt

or

  cipher.decrypt

on the Cipher instance. This should be the first call after creating
the instance, otherwise configuration that has already been set could
get lost in the process.

=== Choosing a key

Symmetric encryption requires a key that is the same for the encrypting
and for the decrypting party and after initial key establishment should
be kept as private information. There are a lot of ways to create
insecure keys, the most notable is to simply take a password as the key
without processing the password further. A simple and secure way to
create a key for a particular Cipher is

 cipher = OpenSSL::AES256.new(:CFB)
 cipher.encrypt
 key = cipher.random_key # also sets the generated key on the Cipher

If you absolutely need to use passwords as encryption keys, you
should use Password-Based Key Derivation Function 2 (PBKDF2) by
generating the key with the help of the functionality provided by
OpenSSL::PKCS5.pbkdf2_hmac_sha1 or OpenSSL::PKCS5.pbkdf2_hmac.

Although there is Cipher#pkcs5_keyivgen, its use is deprecated and
it should only be used in legacy applications because it does not use
the newer PKCS#5 v2 algorithms.

=== Choosing an IV

The cipher modes CBC, CFB, OFB and CTR all need an "initialization
vector", or short, IV. ECB mode is the only mode that does not require
an IV, but there is almost no legitimate use case for this mode
because of the fact that it does not sufficiently hide plaintext
patterns. Therefore

<b>You should never use ECB mode unless you are absolutely sure that
you absolutely need it</b>

Because of this, you will end up with a mode that explicitly requires
an IV in any case. Note that for backwards compatibility reasons,
setting an IV is not explicitly mandated by the Cipher API. If not
set, OpenSSL itself defaults to an all-zeroes IV ("\0", not the
character). Although the IV can be seen as public information, i.e.
it may be transmitted in public once generated, it should still stay
unpredictable to prevent certain kinds of attacks. Therefore, ideally

<b>Always create a secure random IV for every encryption of your
Cipher</b>

A new, random IV should be created for every encryption of data. Think
of the IV as a nonce (number used once) - it's public but random and
unpredictable. A secure random IV can be created as follows

 cipher = ...
 cipher.encrypt
 key = cipher.random_key
 iv = cipher.random_iv # also sets the generated IV on the Cipher

 Although the key is generally a random value, too, it is a bad choice
 as an IV. There are elaborate ways how an attacker can take advantage
 of such an IV. As a general rule of thumb, exposing the key directly
 or indirectly should be avoided at all cost and exceptions only be
 made with good reason.

=== Calling Cipher#final

ECB (which should not be used) and CBC are both block-based modes.
This means that unlike for the other streaming-based modes, they
operate on fixed-size blocks of data, and therefore they require a
"finalization" step to produce or correctly decrypt the last block of
data by appropriately handling some form of padding. Therefore it is
essential to add the output of OpenSSL::Cipher#final to your
encryption/decryption buffer or you will end up with decryption errors
or truncated data.

Although this is not really necessary for streaming-mode ciphers, it is
still recommended to apply the same pattern of adding the output of
Cipher#final there as well - it also enables you to switch between
modes more easily in the future.

=== Encrypting and decrypting some data

  data = "Very, very confidential data"

  cipher = OpenSSL::Cipher::AES.new(128, :CBC)
  cipher.encrypt
  key = cipher.random_key
  iv = cipher.random_iv

  encrypted = cipher.update(data) + cipher.final
  ...
  decipher = OpenSSL::Cipher::AES.new(128, :CBC)
  decipher.decrypt
  decipher.key = key
  decipher.iv = iv

  plain = decipher.update(encrypted) + decipher.final

  puts data == plain #=> true

=== Authenticated Encryption and Associated Data (AEAD)

If the OpenSSL version used supports it, an Authenticated Encryption
mode (such as GCM or CCM) should always be preferred over any
unauthenticated mode. Currently, OpenSSL supports AE only in combination
with Associated Data (AEAD) where additional associated data is included
in the encryption process to compute a tag at the end of the encryption.
This tag will also be used in the decryption process and by verifying
its validity, the authenticity of a given ciphertext is established.

This is superior to unauthenticated modes in that it allows to detect
if somebody effectively changed the ciphertext after it had been
encrypted. This prevents malicious modifications of the ciphertext that
could otherwise be exploited to modify ciphertexts in ways beneficial to
potential attackers.

If no associated data is needed for encryption and later decryption,
the OpenSSL library still requires a value to be set - "" may be used in
case none is available. An example using the GCM (Galois Counter Mode):

  cipher = OpenSSL::Cipher::AES.new(128, :GCM)
  cipher.encrypt
  key = cipher.random_key
  iv = cipher.random_iv
  cipher.auth_data = ""

  encrypted = cipher.update(data) + cipher.final
  tag = cipher.auth_tag

  decipher = OpenSSL::Cipher::AES.new(128, :GCM)
  decipher.decrypt
  decipher.key = key
  decipher.iv = iv
  decipher.auth_tag = tag
  decipher.auth_data = ""

  plain = decipher.update(encrypted) + decipher.final

  puts data == plain #=> true

In Files

  • ext/openssl/ossl_cipher.c

Parent

eOSSLError


class OpenSSL::Config - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Config

In Files

  • ext/openssl/lib/openssl/config.rb
  • ext/openssl/ossl.c

Parent

Object

Included Modules

  • Enumerable

Constants

DEFAULT_CONFIG_FILE
ESCAPE_MAP

escaped char map

QUOTE_REGEXP_DQ

escape with backslash and doubled dq

QUOTE_REGEXP_SQ

escape with backslash

Public Class Methods

new(filename = nil) click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 212
def initialize(filename = nil)
  @data = {}
  if filename
    File.open(filename.to_s) do |file|
      Config.parse_config(file).each do |section, hash|
        self[section] = hash
      end
    end
  end
end
parse(str) click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 20
def parse(str)
  c = new()
  parse_config(StringIO.new(str)).each do |section, hash|
    c[section] = hash
  end
  c
end
parse_config(io) click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 30
def parse_config(io)
  begin
    parse_config_lines(io)
  rescue ConfigError => e
    e.message.replace("error in line #{io.lineno}: " + e.message)
    raise
  end
end

Public Instance Methods

[](section) click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 248
def [](section)
  @data[section] || {}
end
[]=(section, pairs) click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 257
def []=(section, pairs)
  check_modify
  @data[section] ||= {}
  pairs.each do |key, value|
    self.add_value(section, key, value)
  end
end
add_value(section, key, value) click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 243
def add_value(section, key, value)
  check_modify
  (@data[section] ||= {})[key] = value
end
each() { |section, key, value| ... } click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 281
def each
  @data.each do |section, hash|
    hash.each do |key, value|
      yield [section, key, value]
    end
  end
end
get_value(section, key) click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 223
def get_value(section, key)
  if section.nil?
    raise TypeError.new('nil not allowed')
  end
  section = 'default' if section.empty?
  get_key_string(section, key)
end
inspect() click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 289
def inspect
  "#<#{self.class.name} sections=#{sections.inspect}>"
end
section(name) click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 252
def section(name)
  warn('Config#section is deprecated; use Config#[]')
  @data[name] || {}
end
sections() click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 265
def sections
  @data.keys
end
to_s() click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 269
def to_s
  ary = []
  @data.keys.sort.each do |section|
    ary << "[ #{section} ]\n"
    @data[section].keys.each do |key|
      ary << "#{key}=#{@data[section][key]}\n"
    end
    ary << "\n"
  end
  ary.join
end
value(arg1, arg2 = nil) click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 231
def value(arg1, arg2 = nil)
  warn('Config#value is deprecated; use Config#get_value')
  if arg2.nil?
    section, key = 'default', arg1
  else
    section, key = arg1, arg2
  end
  section ||= 'default'
  section = 'default' if section.empty?
  get_key_string(section, key)
end

Protected Instance Methods

data() click to toggle source
# File ext/openssl/lib/openssl/config.rb, line 295
def data
  @data
end


class OpenSSL::ConfigError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::ConfigError

In Files

  • ext/openssl/ossl.c

Parent

eOSSLError


class OpenSSL::Digest - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Digest

OpenSSL::Digest allows you to compute message digests (sometimes interchangeably called “hashes”) of arbitrary data that are cryptographically secure, i.e. a Digest implements a secure one-way function.

One-way functions offer some useful properties. E.g. given two distinct inputs the probability that both yield the same output is highly unlikely. Combined with the fact that every message digest algorithm has a fixed-length output of just a few bytes, digests are often used to create unique identifiers for arbitrary data. A common example is the creation of a unique id for binary documents that are stored in a database.

Another useful characteristic of one-way functions (and thus the name) is that given a digest there is no indication about the original data that produced it, i.e. the only way to identify the original input is to “brute-force” through every possible combination of inputs.

These characteristics make one-way functions also ideal companions for public key signature algorithms: instead of signing an entire document, first a hash of the document is produced with a considerably faster message digest algorithm and only the few bytes of its output need to be signed using the slower public key algorithm. To validate the integrity of a signed document, it suffices to re-compute the hash and verify that it is equal to that in the signature.

Among the supported message digest algorithms are:

  • SHA, SHA1, SHA224, SHA256, SHA384 and SHA512

  • MD2, MD4, MDC2 and MD5

  • RIPEMD160

  • DSS, DSS1 (Pseudo algorithms to be used for DSA signatures. DSS is equal to SHA and DSS1 is equal to SHA1)

For each of these algorithms, there is a sub-class of Digest that can be instantiated as simply as e.g.

digest = OpenSSL::Digest::SHA1.new

Mapping between Digest class and sn/ln

The sn (short names) and ln (long names) are defined in <openssl/object.h> and <openssl/obj_mac.h>. They are textual representations of ASN.1 OBJECT IDENTIFIERs. Each supported digest algorithm has an OBJECT IDENTIFIER associated to it and those again have short/long names assigned to them. E.g. the OBJECT IDENTIFIER for SHA-1 is 1.3.14.3.2.26 and its sn is “SHA1” and its ln is “sha1”.

MD2

  • sn: MD2

  • ln: md2

MD4

  • sn: MD4

  • ln: md4

MD5

  • sn: MD5

  • ln: md5

SHA

  • sn: SHA

  • ln: SHA

SHA-1

  • sn: SHA1

  • ln: sha1

SHA-224

  • sn: SHA224

  • ln: sha224

SHA-256

  • sn: SHA256

  • ln: sha256

SHA-384

  • sn: SHA384

  • ln: sha384

SHA-512

  • sn: SHA512

  • ln: sha512

“Breaking” a message digest algorithm means defying its one-way function characteristics, i.e. producing a collision or finding a way to get to the original data by means that are more efficient than brute-forcing etc. Most of the supported digest algorithms can be considered broken in this sense, even the very popular MD5 and SHA1 algorithms. Should security be your highest concern, then you should probably rely on SHA224, SHA256, SHA384 or SHA512.

Hashing a file

data = File.read('document')
sha256 = OpenSSL::Digest::SHA256.new
digest = sha256.digest(data)

Hashing several pieces of data at once

data1 = File.read('file1')
data2 = File.read('file2')
data3 = File.read('file3')
sha256 = OpenSSL::Digest::SHA256.new
sha256 << data1
sha256 << data2
sha256 << data3
digest = sha256.digest

Reuse a Digest instance

data1 = File.read('file1')
sha256 = OpenSSL::Digest::SHA256.new
digest1 = sha256.digest(data1)

data2 = File.read('file2')
sha256.reset
digest2 = sha256.digest(data2)

In Files

  • lib/rubygems/security.rb
  • ext/openssl/lib/openssl/digest.rb
  • ext/openssl/ossl.c

Parent

OpenSSL::Digest::Class

Public Class Methods

digest(name, data) click to toggle source

Return the data hash computed with name Digest. name is either the long name or short name of a supported digest algorithm.

Examples

OpenSSL::Digest.digest("SHA256", "abc")

which is equivalent to:

OpenSSL::Digest::SHA256.digest("abc")
# File ext/openssl/lib/openssl/digest.rb, line 40
def self.digest(name, data)
    super(data, name)
end
new(string [, data]) → Digest click to toggle source

Creates a Digest instance based on string, which is either the ln (long name) or sn (short name) of a supported digest algorithm. If data (a String) is given, it is used as the initial input to the Digest instance, i.e.

digest = OpenSSL::Digest.new('sha256', 'digestdata')

is equal to

digest = OpenSSL::Digest.new('sha256')
digest.update('digestdata')

Example

digest = OpenSSL::Digest.new('sha1')
static VALUE
ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
{
    EVP_MD_CTX *ctx;
    const EVP_MD *md;
    VALUE type, data;

    rb_scan_args(argc, argv, "11", &type, &data);
    md = GetDigestPtr(type);
    if (!NIL_P(data)) StringValue(data);

    GetDigest(self, ctx);
    if (EVP_DigestInit_ex(ctx, md, NULL) != 1) {
        ossl_raise(eDigestError, "Digest initialization failed.");
    }

    if (!NIL_P(data)) return ossl_digest_update(self, data);
    return self;
}

Public Instance Methods

<<(p1) click to toggle source
Alias for: update
block_length → integer click to toggle source

Returns the block length of the digest algorithm, i.e. the length in bytes of an individual block. Most modern algorithms partition a message to be digested into a sequence of fix-sized blocks that are processed consecutively.

Example

digest = OpenSSL::Digest::SHA1.new
puts digest.block_length # => 64

static VALUE
ossl_digest_block_length(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);

    return INT2NUM(EVP_MD_CTX_block_size(ctx));
}
digest_length → integer click to toggle source

Returns the output size of the digest, i.e. the length in bytes of the final message digest result.

Example

digest = OpenSSL::Digest::SHA1.new
puts digest.digest_length # => 20

static VALUE
ossl_digest_size(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);

    return INT2NUM(EVP_MD_CTX_size(ctx));
}
name → string click to toggle source

Returns the sn of this Digest instance.

Example

digest = OpenSSL::Digest::SHA512.new
puts digest.name # => SHA512

static VALUE
ossl_digest_name(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);

    return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx)));
}
reset → self click to toggle source

Resets the Digest in the sense that any #update that has been performed is abandoned and the Digest is set to its initial state again.

static VALUE
ossl_digest_reset(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);
    if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) {
        ossl_raise(eDigestError, "Digest initialization failed.");
    }

    return self;
}
update(string) → aString click to toggle source

Not every message digest can be computed in one single pass. If a message digest is to be computed from several subsequent sources, then each may be passed individually to the Digest instance.

Example

digest = OpenSSL::Digest::SHA256.new
digest.update('First input')
digest << 'Second input' # equivalent to digest.update('Second input')
result = digest.digest
VALUE
ossl_digest_update(VALUE self, VALUE data)
{
    EVP_MD_CTX *ctx;

    StringValue(data);
    GetDigest(self, ctx);
    EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data));

    return self;
}
Also aliased as: <<


class OpenSSL::Digest::Digest - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Digest::Digest

This class is only provided for backwards compatibility. Use OpenSSL::Digest in the future.

In Files

  • ext/openssl/lib/openssl/digest.rb

Parent

OpenSSL::Digest

Public Class Methods

new(*args) click to toggle source
# File ext/openssl/lib/openssl/digest.rb, line 64
def initialize(*args)
  # add warning
  super(*args)
end


class OpenSSL::Digest::DigestError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Digest::DigestError

Generic Exception class that is raised if an error occurs during a Digest operation.

In Files

  • ext/openssl/ossl_digest.c

Parent

eOSSLError


class OpenSSL::Engine - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Engine

In Files

  • ext/openssl/ossl.c

Parent

Object

Public Class Methods

by_id(p1) click to toggle source
static VALUE
ossl_engine_s_by_id(VALUE klass, VALUE id)
{
    ENGINE *e;
    VALUE obj;

    StringValue(id);
    ossl_engine_s_load(1, &id, klass);
    if(!(e = ENGINE_by_id(RSTRING_PTR(id))))
        ossl_raise(eEngineError, NULL);
    WrapEngine(klass, obj, e);
    if(rb_block_given_p()) rb_yield(obj);
    if(!ENGINE_init(e))
        ossl_raise(eEngineError, NULL);
    ENGINE_ctrl(e, ENGINE_CTRL_SET_PASSWORD_CALLBACK,
                0, NULL, (void(*)(void))ossl_pem_passwd_cb);
    ERR_clear_error();

    return obj;
}
cleanup() click to toggle source
static VALUE
ossl_engine_s_cleanup(VALUE self)
{
#if defined(HAVE_ENGINE_CLEANUP)
    ENGINE_cleanup();
#endif
    return Qnil;
}
engines() click to toggle source
static VALUE
ossl_engine_s_engines(VALUE klass)
{
    ENGINE *e;
    VALUE ary, obj;

    ary = rb_ary_new();
    for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)){
        /* Need a ref count of two here because of ENGINE_free being
         * called internally by OpenSSL when moving to the next ENGINE
         * and by us when releasing the ENGINE reference */
        ENGINE_up_ref(e);
        WrapEngine(klass, obj, e);
        rb_ary_push(ary, obj);
    }

    return ary;
}
load(p1 = v1) click to toggle source
static VALUE
ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
{
#if !defined(HAVE_ENGINE_LOAD_BUILTIN_ENGINES)
    return Qnil;
#else
    VALUE name;

    rb_scan_args(argc, argv, "01", &name);
    if(NIL_P(name)){
        ENGINE_load_builtin_engines();
        return Qtrue;
    }
    StringValue(name);
#ifndef OPENSSL_NO_STATIC_ENGINE
#if HAVE_ENGINE_LOAD_DYNAMIC
    OSSL_ENGINE_LOAD_IF_MATCH(dynamic);
#endif
#if HAVE_ENGINE_LOAD_4758CCA
    OSSL_ENGINE_LOAD_IF_MATCH(4758cca);
#endif
#if HAVE_ENGINE_LOAD_AEP
    OSSL_ENGINE_LOAD_IF_MATCH(aep);
#endif
#if HAVE_ENGINE_LOAD_ATALLA
    OSSL_ENGINE_LOAD_IF_MATCH(atalla);
#endif
#if HAVE_ENGINE_LOAD_CHIL
    OSSL_ENGINE_LOAD_IF_MATCH(chil);
#endif
#if HAVE_ENGINE_LOAD_CSWIFT
    OSSL_ENGINE_LOAD_IF_MATCH(cswift);
#endif
#if HAVE_ENGINE_LOAD_NURON
    OSSL_ENGINE_LOAD_IF_MATCH(nuron);
#endif
#if HAVE_ENGINE_LOAD_SUREWARE
    OSSL_ENGINE_LOAD_IF_MATCH(sureware);
#endif
#if HAVE_ENGINE_LOAD_UBSEC
    OSSL_ENGINE_LOAD_IF_MATCH(ubsec);
#endif
#if HAVE_ENGINE_LOAD_PADLOCK
    OSSL_ENGINE_LOAD_IF_MATCH(padlock);
#endif
#if HAVE_ENGINE_LOAD_CAPI
    OSSL_ENGINE_LOAD_IF_MATCH(capi);
#endif
#if HAVE_ENGINE_LOAD_GMP
    OSSL_ENGINE_LOAD_IF_MATCH(gmp);
#endif
#if HAVE_ENGINE_LOAD_GOST
    OSSL_ENGINE_LOAD_IF_MATCH(gost);
#endif
#if HAVE_ENGINE_LOAD_CRYPTODEV
    OSSL_ENGINE_LOAD_IF_MATCH(cryptodev);
#endif
#if HAVE_ENGINE_LOAD_AESNI
    OSSL_ENGINE_LOAD_IF_MATCH(aesni);
#endif
#endif
#ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO
    OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto);
#endif
    OSSL_ENGINE_LOAD_IF_MATCH(openssl);
    rb_warning("no such builtin loader for `%s'", RSTRING_PTR(name));
    return Qnil;
#endif /* HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
}

Public Instance Methods

cipher(p1) click to toggle source
static VALUE
ossl_engine_get_cipher(VALUE self, VALUE name)
{
    ENGINE *e;
    const EVP_CIPHER *ciph, *tmp;
    char *s;
    int nid;

    s = StringValuePtr(name);
    tmp = EVP_get_cipherbyname(s);
    if(!tmp) ossl_raise(eEngineError, "no such cipher `%s'", s);
    nid = EVP_CIPHER_nid(tmp);
    GetEngine(self, e);
    ciph = ENGINE_get_cipher(e, nid);
    if(!ciph) ossl_raise(eEngineError, NULL);

    return ossl_cipher_new(ciph);
}
cmds() click to toggle source
static VALUE
ossl_engine_get_cmds(VALUE self)
{
    ENGINE *e;
    const ENGINE_CMD_DEFN *defn, *p;
    VALUE ary, tmp;

    GetEngine(self, e);
    ary = rb_ary_new();
    if ((defn = ENGINE_get_cmd_defns(e)) != NULL){
        for (p = defn; p->cmd_num > 0; p++){
            tmp = rb_ary_new();
            rb_ary_push(tmp, rb_str_new2(p->cmd_name));
            rb_ary_push(tmp, rb_str_new2(p->cmd_desc));
            rb_ary_push(tmp, ossl_engine_cmd_flag_to_name(p->cmd_flags));
            rb_ary_push(ary, tmp);
        }
    }

    return ary;
}
ctrl_cmd(p1, p2 = v2) click to toggle source
static VALUE
ossl_engine_ctrl_cmd(int argc, VALUE *argv, VALUE self)
{
    ENGINE *e;
    VALUE cmd, val;
    int ret;

    GetEngine(self, e);
    rb_scan_args(argc, argv, "11", &cmd, &val);
    StringValue(cmd);
    if (!NIL_P(val)) StringValue(val);
    ret = ENGINE_ctrl_cmd_string(e, RSTRING_PTR(cmd),
                                 NIL_P(val) ? NULL : RSTRING_PTR(val), 0);
    if (!ret) ossl_raise(eEngineError, NULL);

    return self;
}
digest(p1) click to toggle source
static VALUE
ossl_engine_get_digest(VALUE self, VALUE name)
{
    ENGINE *e;
    const EVP_MD *md, *tmp;
    char *s;
    int nid;

    s = StringValuePtr(name);
    tmp = EVP_get_digestbyname(s);
    if(!tmp) ossl_raise(eEngineError, "no such digest `%s'", s);
    nid = EVP_MD_nid(tmp);
    GetEngine(self, e);
    md = ENGINE_get_digest(e, nid);
    if(!md) ossl_raise(eEngineError, NULL);

    return ossl_digest_new(md);
}
finish() click to toggle source
static VALUE
ossl_engine_finish(VALUE self)
{
    ENGINE *e;

    GetEngine(self, e);
    if(!ENGINE_finish(e)) ossl_raise(eEngineError, NULL);

    return Qnil;
}
id() click to toggle source
static VALUE
ossl_engine_get_id(VALUE self)
{
    ENGINE *e;
    GetEngine(self, e);
    return rb_str_new2(ENGINE_get_id(e));
}
inspect() click to toggle source
static VALUE
ossl_engine_inspect(VALUE self)
{
    ENGINE *e;

    GetEngine(self, e);
    return rb_sprintf("#<%"PRIsVALUE" id=\"%s\" name=\"%s\">",
                      rb_obj_class(self), ENGINE_get_id(e), ENGINE_get_name(e));
}
load_private_key(p1 = v1, p2 = v2) click to toggle source
static VALUE
ossl_engine_load_privkey(int argc, VALUE *argv, VALUE self)
{
    ENGINE *e;
    EVP_PKEY *pkey;
    VALUE id, data, obj;
    char *sid, *sdata;

    rb_scan_args(argc, argv, "02", &id, &data);
    sid = NIL_P(id) ? NULL : StringValuePtr(id);
    sdata = NIL_P(data) ? NULL : StringValuePtr(data);
    GetEngine(self, e);
#if OPENSSL_VERSION_NUMBER < 0x00907000L
    pkey = ENGINE_load_private_key(e, sid, sdata);
#else
    pkey = ENGINE_load_private_key(e, sid, NULL, sdata);
#endif
    if (!pkey) ossl_raise(eEngineError, NULL);
    obj = ossl_pkey_new(pkey);
    OSSL_PKEY_SET_PRIVATE(obj);

    return obj;
}
load_public_key(p1 = v1, p2 = v2) click to toggle source
static VALUE
ossl_engine_load_pubkey(int argc, VALUE *argv, VALUE self)
{
    ENGINE *e;
    EVP_PKEY *pkey;
    VALUE id, data;
    char *sid, *sdata;

    rb_scan_args(argc, argv, "02", &id, &data);
    sid = NIL_P(id) ? NULL : StringValuePtr(id);
    sdata = NIL_P(data) ? NULL : StringValuePtr(data);
    GetEngine(self, e);
#if OPENSSL_VERSION_NUMBER < 0x00907000L
    pkey = ENGINE_load_public_key(e, sid, sdata);
#else
    pkey = ENGINE_load_public_key(e, sid, NULL, sdata);
#endif
    if (!pkey) ossl_raise(eEngineError, NULL);

    return ossl_pkey_new(pkey);
}
name() click to toggle source
static VALUE
ossl_engine_get_name(VALUE self)
{
    ENGINE *e;
    GetEngine(self, e);
    return rb_str_new2(ENGINE_get_name(e));
}
set_default(p1) click to toggle source
static VALUE
ossl_engine_set_default(VALUE self, VALUE flag)
{
    ENGINE *e;
    int f = NUM2INT(flag);

    GetEngine(self, e);
    ENGINE_set_default(e, f);

    return Qtrue;
}


class OpenSSL::Engine::EngineError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Engine::EngineError

In Files

  • ext/openssl/ossl_digest.c

Parent

eOSSLError


class OpenSSL::HMAC - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::HMAC

In Files

  • ext/openssl/ossl.c

Parent

Object

Public Class Methods

digest(digest, key, data) → aString click to toggle source
static VALUE
ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)
{
    unsigned char *buf;
    unsigned int buf_len;

    StringValue(key);
    StringValue(data);
    buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LENINT(key),
               (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);

    return rb_str_new((const char *)buf, buf_len);
}
digest(digest, key, data) → aString click to toggle source
static VALUE
ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data)
{
    unsigned char *buf;
    char *hexbuf;
    unsigned int buf_len;
    VALUE hexdigest;

    StringValue(key);
    StringValue(data);

    buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LENINT(key),
               (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);
    if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * (int)buf_len) {
        ossl_raise(eHMACError, "Cannot convert buf to hexbuf");
    }
    hexdigest = ossl_buf2str(hexbuf, 2 * buf_len);

    return hexdigest;
}
new(key, digest) → hmac click to toggle source
static VALUE
ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
{
    HMAC_CTX *ctx;

    StringValue(key);
    GetHMAC(self, ctx);
    HMAC_Init(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
                 GetDigestPtr(digest));

    return self;
}

Public Instance Methods

<<(p1) click to toggle source
Alias for: update
digest → aString click to toggle source
static VALUE
ossl_hmac_digest(VALUE self)
{
    HMAC_CTX *ctx;
    unsigned char *buf;
    unsigned int buf_len;
    VALUE digest;

    GetHMAC(self, ctx);
    hmac_final(ctx, &buf, &buf_len);
    digest = ossl_buf2str((char *)buf, buf_len);

    return digest;
}
hexdigest → aString click to toggle source
static VALUE
ossl_hmac_hexdigest(VALUE self)
{
    HMAC_CTX *ctx;
    unsigned char *buf;
    char *hexbuf;
    unsigned int buf_len;
    VALUE hexdigest;

    GetHMAC(self, ctx);
    hmac_final(ctx, &buf, &buf_len);
    if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * (int)buf_len) {
        OPENSSL_free(buf);
        ossl_raise(eHMACError, "Memory alloc error");
    }
    OPENSSL_free(buf);
    hexdigest = ossl_buf2str(hexbuf, 2 * buf_len);

    return hexdigest;
}
Also aliased as: inspect, to_s
inspect() click to toggle source
Alias for: hexdigest
reset → self click to toggle source
static VALUE
ossl_hmac_reset(VALUE self)
{
    HMAC_CTX *ctx;

    GetHMAC(self, ctx);
    HMAC_Init(ctx, NULL, 0, NULL);

    return self;
}
to_s() click to toggle source
Alias for: hexdigest
update(string) → self click to toggle source
static VALUE
ossl_hmac_update(VALUE self, VALUE data)
{
    HMAC_CTX *ctx;

    StringValue(data);
    GetHMAC(self, ctx);
    HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data));

    return self;
}
Also aliased as: <<


class OpenSSL::HMACError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::HMACError

In Files

  • ext/openssl/ossl.c

Parent

eOSSLError


module OpenSSL::Netscape - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::Netscape

OpenSSL::Netscape is a namespace for SPKI (Simple Public Key Infrastructure) which implements Signed Public Key and Challenge. See RFC 2692 and RFC 2693 for details.

In Files

  • ext/openssl/ossl.c


class OpenSSL::Netscape::SPKI - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Netscape::SPKI

A Simple Public Key Infrastructure implementation (pronounced “spookey”). The structure is defined as

PublicKeyAndChallenge ::= SEQUENCE {
  spki SubjectPublicKeyInfo,
  challenge IA5STRING
}

SignedPublicKeyAndChallenge ::= SEQUENCE {
  publicKeyAndChallenge PublicKeyAndChallenge,
  signatureAlgorithm AlgorithmIdentifier,
  signature BIT STRING
}

where the definitions of SubjectPublicKeyInfo and AlgorithmIdentifier can be found in RFC5280. SPKI is typically used in browsers for generating a public/private key pair and a subsequent certificate request, using the HTML <keygen> element.

Examples

Creating an SPKI

key = OpenSSL::PKey::RSA.new 2048
spki = OpenSSL::Netscape::SPKI.new
spki.challenge = "RandomChallenge"
spki.public_key = key.public_key
spki.sign(key, OpenSSL::Digest::SHA256.new)
#send a request containing this to a server generating a certificate

Verifiying an SPKI request

request = #...
spki = OpenSSL::Netscape::SPKI.new request
unless spki.verify(spki.public_key)
  # signature is invalid
end
#proceed

In Files

  • ext/openssl/ossl_ns_spki.c

Parent

Object

Public Class Methods

new([request]) → spki click to toggle source

Parameters

  • request - optional raw request, either in PEM or DER format.

static VALUE
ossl_spki_initialize(int argc, VALUE *argv, VALUE self)
{
    NETSCAPE_SPKI *spki;
    VALUE buffer;
    const unsigned char *p;

    if (rb_scan_args(argc, argv, "01", &buffer) == 0) {
        return self;
    }
    StringValue(buffer);
    if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), -1))) {
        p = (unsigned char *)RSTRING_PTR(buffer);
        if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) {
            ossl_raise(eSPKIError, NULL);
        }
    }
    NETSCAPE_SPKI_free(DATA_PTR(self));
    DATA_PTR(self) = spki;
    ERR_clear_error();

    return self;
}

Public Instance Methods

challenge → string click to toggle source

Returns the challenge string associated with this SPKI.

static VALUE
ossl_spki_get_challenge(VALUE self)
{
    NETSCAPE_SPKI *spki;

    GetSPKI(self, spki);
    if (spki->spkac->challenge->length <= 0) {
        OSSL_Debug("Challenge.length <= 0?");
        return rb_str_new(0, 0);
    }

    return rb_str_new((const char *)spki->spkac->challenge->data,
                      spki->spkac->challenge->length);
}
challenge = str → string click to toggle source

Parameters

  • str - the challenge string to be set for this instance

Sets the challenge to be associated with the SPKI. May be used by the server, e.g. to prevent replay.

static VALUE
ossl_spki_set_challenge(VALUE self, VALUE str)
{
    NETSCAPE_SPKI *spki;

    StringValue(str);
    GetSPKI(self, spki);
    if (!ASN1_STRING_set(spki->spkac->challenge, RSTRING_PTR(str),
                         RSTRING_LENINT(str))) {
        ossl_raise(eSPKIError, NULL);
    }

    return str;
}
public_key → pkey click to toggle source

Returns the public key associated with the SPKI, an instance of OpenSSL::PKey.

static VALUE
ossl_spki_get_public_key(VALUE self)
{
    NETSCAPE_SPKI *spki;
    EVP_PKEY *pkey;

    GetSPKI(self, spki);
    if (!(pkey = NETSCAPE_SPKI_get_pubkey(spki))) { /* adds an reference */
        ossl_raise(eSPKIError, NULL);
    }

    return ossl_pkey_new(pkey); /* NO DUP - OK */
}
public_key = pub → pkey click to toggle source

Parameters

  • pub - the public key to be set for this instance

Sets the public key to be associated with the SPKI, an instance of OpenSSL::PKey. This should be the public key corresponding to the private key used for signing the SPKI.

static VALUE
ossl_spki_set_public_key(VALUE self, VALUE key)
{
    NETSCAPE_SPKI *spki;

    GetSPKI(self, spki);
    if (!NETSCAPE_SPKI_set_pubkey(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
        ossl_raise(eSPKIError, NULL);
    }

    return key;
}
sign(key, digest) → spki click to toggle source

Parameters

  • key - the private key to be used for signing this instance

  • digest - the digest to be used for signing this instance

To sign an SPKI, the private key corresponding to the public key set for this instance should be used, in addition to a digest algorithm in the form of an OpenSSL::Digest. The private key should be an instance of OpenSSL::PKey.

static VALUE
ossl_spki_sign(VALUE self, VALUE key, VALUE digest)
{
    NETSCAPE_SPKI *spki;
    EVP_PKEY *pkey;
    const EVP_MD *md;

    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
    md = GetDigestPtr(digest);
    GetSPKI(self, spki);
    if (!NETSCAPE_SPKI_sign(spki, pkey, md)) {
        ossl_raise(eSPKIError, NULL);
    }

    return self;
}
to_der → DER-encoded string click to toggle source

Returns the DER encoding of this SPKI.

static VALUE
ossl_spki_to_der(VALUE self)
{
    NETSCAPE_SPKI *spki;
    VALUE str;
    long len;
    unsigned char *p;

    GetSPKI(self, spki);
    if ((len = i2d_NETSCAPE_SPKI(spki, NULL)) <= 0)
        ossl_raise(eX509CertError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if (i2d_NETSCAPE_SPKI(spki, &p) <= 0)
        ossl_raise(eX509CertError, NULL);
    ossl_str_adjust(str, p);

    return str;
}
to_pem → PEM-encoded string click to toggle source

Returns the PEM encoding of this SPKI.

static VALUE
ossl_spki_to_pem(VALUE self)
{
    NETSCAPE_SPKI *spki;
    char *data;
    VALUE str;

    GetSPKI(self, spki);
    if (!(data = NETSCAPE_SPKI_b64_encode(spki))) {
        ossl_raise(eSPKIError, NULL);
    }
    str = ossl_buf2str(data, rb_long2int(strlen(data)));

    return str;
}
Also aliased as: to_s
to_s() click to toggle source
Alias for: to_pem
to_text → string click to toggle source

Returns a textual representation of this SPKI, useful for debugging purposes.

static VALUE
ossl_spki_print(VALUE self)
{
    NETSCAPE_SPKI *spki;
    BIO *out;
    BUF_MEM *buf;
    VALUE str;

    GetSPKI(self, spki);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eSPKIError, NULL);
    }
    if (!NETSCAPE_SPKI_print(out, spki)) {
        BIO_free(out);
        ossl_raise(eSPKIError, NULL);
    }
    BIO_get_mem_ptr(out, &buf);
    str = rb_str_new(buf->data, buf->length);
    BIO_free(out);

    return str;
}
verify(key) → boolean click to toggle source

Parameters

  • key - the public key to be used for verifying the SPKI signature

Returns true if the signature is valid, false otherwise. To verify an SPKI, the public key contained within the SPKI should be used.

static VALUE
ossl_spki_verify(VALUE self, VALUE key)
{
    NETSCAPE_SPKI *spki;

    GetSPKI(self, spki);
    switch (NETSCAPE_SPKI_verify(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
    case 0:
        return Qfalse;
    case 1:
        return Qtrue;
    default:
        ossl_raise(eSPKIError, NULL);
    }
    return Qnil; /* dummy */
}


class OpenSSL::Netscape::SPKIError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Netscape::SPKIError

Generic Exception class that is raised if an error occurs during an operation on an instance of OpenSSL::Netscape::SPKI.

In Files

  • ext/openssl/ossl_ns_spki.c

Parent

eOSSLError


module OpenSSL::OCSP - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::OCSP

In Files

  • ext/openssl/ossl.c


class OpenSSL::OCSP::BasicResponse - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::OCSP::BasicResponse

In Files

  • ext/openssl/ossl_ns_spki.c

Parent

Object

Public Class Methods

new(*args) click to toggle source
static VALUE
ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)
{
    return self;
}

Public Instance Methods

add_nonce(p1 = v1) click to toggle source
static VALUE
ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self)
{
    OCSP_BASICRESP *bs;
    VALUE val;
    int ret;

    rb_scan_args(argc, argv, "01", &val);
    if(NIL_P(val)) {
        GetOCSPBasicRes(self, bs);
        ret = OCSP_basic_add1_nonce(bs, NULL, -1);
    }
    else{
        StringValue(val);
        GetOCSPBasicRes(self, bs);
        ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val));
    }
    if(!ret) ossl_raise(eOCSPError, NULL);

    return self;
}
add_status(p1, p2, p3, p4, p5, p6, p7) click to toggle source
static VALUE
ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
                         VALUE reason, VALUE revtime,
                         VALUE thisupd, VALUE nextupd, VALUE ext)
{
    OCSP_BASICRESP *bs;
    OCSP_SINGLERESP *single;
    OCSP_CERTID *id;
    int st, rsn;
    ASN1_TIME *ths, *nxt, *rev;
    int error, i, rstatus = 0;
    VALUE tmp;

    st = NUM2INT(status);
    rsn = NIL_P(status) ? 0 : NUM2INT(reason);
    if(!NIL_P(ext)){
        /* All ary's members should be X509Extension */
        Check_Type(ext, T_ARRAY);
        for (i = 0; i < RARRAY_LEN(ext); i++)
            OSSL_Check_Kind(RARRAY_PTR(ext)[i], cX509Ext);
    }

    error = 0;
    ths = nxt = rev = NULL;
    if(!NIL_P(revtime)){
        tmp = rb_protect(rb_Integer, revtime, &rstatus);
        if(rstatus) goto err;
        rev = X509_gmtime_adj(NULL, NUM2INT(tmp));
    }
    tmp = rb_protect(rb_Integer, thisupd, &rstatus);
    if(rstatus) goto err;
    ths = X509_gmtime_adj(NULL, NUM2INT(tmp));
    tmp = rb_protect(rb_Integer, nextupd, &rstatus);
    if(rstatus) goto err;
    nxt = X509_gmtime_adj(NULL, NUM2INT(tmp));

    GetOCSPBasicRes(self, bs);
    SafeGetOCSPCertId(cid, id);
    if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){
        error = 1;
        goto err;
    }

    if(!NIL_P(ext)){
        X509_EXTENSION *x509ext;
        sk_X509_EXTENSION_pop_free(single->singleExtensions, X509_EXTENSION_free);
        single->singleExtensions = NULL;
        for(i = 0; i < RARRAY_LEN(ext); i++){
            x509ext = DupX509ExtPtr(RARRAY_PTR(ext)[i]);
            if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){
                X509_EXTENSION_free(x509ext);
                error = 1;
                goto err;
            }
            X509_EXTENSION_free(x509ext);
        }
    }

 err:
    ASN1_TIME_free(ths);
    ASN1_TIME_free(nxt);
    ASN1_TIME_free(rev);
    if(error) ossl_raise(eOCSPError, NULL);
    if(rstatus) rb_jump_tag(rstatus);

    return self;
}
copy_nonce(p1) click to toggle source
static VALUE
ossl_ocspbres_copy_nonce(VALUE self, VALUE request)
{
    OCSP_BASICRESP *bs;
    OCSP_REQUEST *req;
    int ret;

    GetOCSPBasicRes(self, bs);
    SafeGetOCSPReq(request, req);
    ret = OCSP_copy_nonce(bs, req);

    return INT2NUM(ret);
}
sign(p1, p2, p3 = v3, p4 = v4) click to toggle source
static VALUE
ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
{
    VALUE signer_cert, signer_key, certs, flags;
    OCSP_BASICRESP *bs;
    X509 *signer;
    EVP_PKEY *key;
    STACK_OF(X509) *x509s;
    unsigned long flg;
    int ret;

    rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags);
    signer = GetX509CertPtr(signer_cert);
    key = GetPrivPKeyPtr(signer_key);
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    if(NIL_P(certs)){
        x509s = sk_X509_new_null();
        flg |= OCSP_NOCERTS;
    }
    else{
        x509s = ossl_x509_ary2sk(certs);
    }
    GetOCSPBasicRes(self, bs);
    ret = OCSP_basic_sign(bs, signer, key, EVP_sha1(), x509s, flg);
    sk_X509_pop_free(x509s, X509_free);
    if(!ret) ossl_raise(eOCSPError, NULL);

    return self;
}
status() click to toggle source
static VALUE
ossl_ocspbres_get_status(VALUE self)
{
    OCSP_BASICRESP *bs;
    OCSP_SINGLERESP *single;
    OCSP_CERTID *cid;
    ASN1_TIME *revtime, *thisupd, *nextupd;
    int status, reason;
    X509_EXTENSION *x509ext;
    VALUE ret, ary, ext;
    int count, ext_count, i, j;

    GetOCSPBasicRes(self, bs);
    ret = rb_ary_new();
    count = OCSP_resp_count(bs);
    for(i = 0; i < count; i++){
        single = OCSP_resp_get0(bs, i);
        if(!single) continue;

        revtime = thisupd = nextupd = NULL;
        status = OCSP_single_get0_status(single, &reason, &revtime,
                                         &thisupd, &nextupd);
        if(status < 0) continue;
        if(!(cid = OCSP_CERTID_dup(single->certId)))
            ossl_raise(eOCSPError, NULL);
        ary = rb_ary_new();
        rb_ary_push(ary, ossl_ocspcertid_new(cid));
        rb_ary_push(ary, INT2NUM(status));
        rb_ary_push(ary, INT2NUM(reason));
        rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil);
        rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil);
        rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil);
        ext = rb_ary_new();
        ext_count = OCSP_SINGLERESP_get_ext_count(single);
        for(j = 0; j < ext_count; j++){
            x509ext = OCSP_SINGLERESP_get_ext(single, j);
            rb_ary_push(ext, ossl_x509ext_new(x509ext));
        }
        rb_ary_push(ary, ext);
        rb_ary_push(ret, ary);
    }

    return ret;
}
verify(p1, p2, p3 = v3) click to toggle source
static VALUE
ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
{
    VALUE certs, store, flags, result;
    OCSP_BASICRESP *bs;
    STACK_OF(X509) *x509s;
    X509_STORE *x509st;
    int flg;

    rb_scan_args(argc, argv, "21", &certs, &store, &flags);
    x509st = GetX509StorePtr(store);
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    x509s = ossl_x509_ary2sk(certs);
    GetOCSPBasicRes(self, bs);
    result = OCSP_basic_verify(bs, x509s, x509st, flg) > 0 ? Qtrue : Qfalse;
    sk_X509_pop_free(x509s, X509_free);
    if(!result) rb_warn("%s", ERR_error_string(ERR_peek_error(), NULL));

    return result;
}


class OpenSSL::OCSP::CertificateId - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::OCSP::CertificateId

In Files

  • ext/openssl/ossl_ns_spki.c

Parent

Object

Public Class Methods

new(p1, p2, p3 = v3) click to toggle source
static VALUE
ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
{
    OCSP_CERTID *id, *newid;
    X509 *x509s, *x509i;
    VALUE subject, issuer, digest;
    const EVP_MD *md;

    if (rb_scan_args(argc, argv, "21", &subject, &issuer, &digest) == 0) {
        return self;
    }

    x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */
    x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */

    if (!NIL_P(digest)) {
        md = GetDigestPtr(digest);
        newid = OCSP_cert_to_id(md, x509s, x509i);
    } else {
        newid = OCSP_cert_to_id(NULL, x509s, x509i);
    }
    if(!newid)
        ossl_raise(eOCSPError, NULL);
    GetOCSPCertId(self, id);
    OCSP_CERTID_free(id);
    RDATA(self)->data = newid;

    return self;
}

Public Instance Methods

cmp(p1) click to toggle source
static VALUE
ossl_ocspcid_cmp(VALUE self, VALUE other)
{
    OCSP_CERTID *id, *id2;
    int result;

    GetOCSPCertId(self, id);
    SafeGetOCSPCertId(other, id2);
    result = OCSP_id_cmp(id, id2);

    return (result == 0) ? Qtrue : Qfalse;
}
cmp_issuer(p1) click to toggle source
static VALUE
ossl_ocspcid_cmp_issuer(VALUE self, VALUE other)
{
    OCSP_CERTID *id, *id2;
    int result;

    GetOCSPCertId(self, id);
    SafeGetOCSPCertId(other, id2);
    result = OCSP_id_issuer_cmp(id, id2);

    return (result == 0) ? Qtrue : Qfalse;
}
serial() click to toggle source
static VALUE
ossl_ocspcid_get_serial(VALUE self)
{
    OCSP_CERTID *id;

    GetOCSPCertId(self, id);

    return asn1integer_to_num(id->serialNumber);
}


class OpenSSL::OCSP::OCSPError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::OCSP::OCSPError

In Files

  • ext/openssl/ossl_ns_spki.c

Parent

eOSSLError


class OpenSSL::OCSP::Request - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::OCSP::Request

In Files

  • ext/openssl/ossl_ns_spki.c

Parent

Object

Public Class Methods

new(p1 = v1) click to toggle source
static VALUE
ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE arg;
    const unsigned char *p;

    rb_scan_args(argc, argv, "01", &arg);
    if(!NIL_P(arg)){
        OCSP_REQUEST *req = DATA_PTR(self), *x;
        arg = ossl_to_der_if_possible(arg);
        StringValue(arg);
        p = (unsigned char*)RSTRING_PTR(arg);
        x = d2i_OCSP_REQUEST(&req, &p, RSTRING_LEN(arg));
        DATA_PTR(self) = req;
        if(!x){
            ossl_raise(eOCSPError, "cannot load DER encoded request");
        }
    }

    return self;
}

Public Instance Methods

add_certid(p1) click to toggle source
static VALUE
ossl_ocspreq_add_certid(VALUE self, VALUE certid)
{
    OCSP_REQUEST *req;
    OCSP_CERTID *id;

    GetOCSPReq(self, req);
    GetOCSPCertId(certid, id);
    if(!OCSP_request_add0_id(req, OCSP_CERTID_dup(id)))
        ossl_raise(eOCSPError, NULL);

    return self;
}
add_nonce(p1 = v1) click to toggle source
static VALUE
ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self)
{
    OCSP_REQUEST *req;
    VALUE val;
    int ret;

    rb_scan_args(argc, argv, "01", &val);
    if(NIL_P(val)) {
        GetOCSPReq(self, req);
        ret = OCSP_request_add1_nonce(req, NULL, -1);
    }
    else{
        StringValue(val);
        GetOCSPReq(self, req);
        ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val));
    }
    if(!ret) ossl_raise(eOCSPError, NULL);

    return self;
}
certid() click to toggle source
static VALUE
ossl_ocspreq_get_certid(VALUE self)
{
    OCSP_REQUEST *req;
    OCSP_ONEREQ *one;
    OCSP_CERTID *id;
    VALUE ary, tmp;
    int i, count;

    GetOCSPReq(self, req);
    count = OCSP_request_onereq_count(req);
    ary = (count > 0) ? rb_ary_new() : Qnil;
    for(i = 0; i < count; i++){
        one = OCSP_request_onereq_get0(req, i);
        if(!(id = OCSP_CERTID_dup(OCSP_onereq_get0_id(one))))
            ossl_raise(eOCSPError, NULL);
        WrapOCSPCertId(cOCSPCertId, tmp, id);
        rb_ary_push(ary, tmp);
    }

    return ary;
}
check_nonce(p1) click to toggle source

Check nonce validity in a request and response. Return value reflects result:

1: nonces present and equal.
2: nonces both absent.
3: nonce present in response only.
0: nonces both present and not equal.

-1: nonce in request only.

For most responders clients can check return > 0.
If responder doesn't handle nonces return != 0 may be
necessary. return == 0 is always an error.
static VALUE
ossl_ocspreq_check_nonce(VALUE self, VALUE basic_resp)
{
    OCSP_REQUEST *req;
    OCSP_BASICRESP *bs;
    int res;

    GetOCSPReq(self, req);
    SafeGetOCSPBasicRes(basic_resp, bs);
    res = OCSP_check_nonce(req, bs);

    return INT2NUM(res);
}
sign(p1, p2, p3 = v3, p4 = v4) click to toggle source
static VALUE
ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
{
    VALUE signer_cert, signer_key, certs, flags;
    OCSP_REQUEST *req;
    X509 *signer;
    EVP_PKEY *key;
    STACK_OF(X509) *x509s;
    unsigned long flg;
    int ret;

    rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags);
    signer = GetX509CertPtr(signer_cert);
    key = GetPrivPKeyPtr(signer_key);
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    if(NIL_P(certs)){
        x509s = sk_X509_new_null();
        flags |= OCSP_NOCERTS;
    }
    else x509s = ossl_x509_ary2sk(certs);
    GetOCSPReq(self, req);
    ret = OCSP_request_sign(req, signer, key, EVP_sha1(), x509s, flg);
    sk_X509_pop_free(x509s, X509_free);
    if(!ret) ossl_raise(eOCSPError, NULL);

    return self;
}
to_der() click to toggle source
static VALUE
ossl_ocspreq_to_der(VALUE self)
{
    OCSP_REQUEST *req;
    VALUE str;
    unsigned char *p;
    long len;

    GetOCSPReq(self, req);
    if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0)
        ossl_raise(eOCSPError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_OCSP_REQUEST(req, &p) <= 0)
        ossl_raise(eOCSPError, NULL);
    ossl_str_adjust(str, p);

    return str;
}
verify(p1, p2, p3 = v3) click to toggle source
static VALUE
ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self)
{
    VALUE certs, store, flags;
    OCSP_REQUEST *req;
    STACK_OF(X509) *x509s;
    X509_STORE *x509st;
    int flg, result;

    rb_scan_args(argc, argv, "21", &certs, &store, &flags);
    x509st = GetX509StorePtr(store);
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    x509s = ossl_x509_ary2sk(certs);
    GetOCSPReq(self, req);
    result = OCSP_request_verify(req, x509s, x509st, flg);
    sk_X509_pop_free(x509s, X509_free);
    if(!result) rb_warn("%s", ERR_error_string(ERR_peek_error(), NULL));

    return result ? Qtrue : Qfalse;
}


class OpenSSL::OCSP::Response - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::OCSP::Response

In Files

  • ext/openssl/ossl_ns_spki.c

Parent

Object

Public Class Methods

create(p1, p2) click to toggle source

OCSP::Response

static VALUE
ossl_ocspres_s_create(VALUE klass, VALUE status, VALUE basic_resp)
{
    OCSP_BASICRESP *bs;
    OCSP_RESPONSE *res;
    VALUE obj;
    int st = NUM2INT(status);

    if(NIL_P(basic_resp)) bs = NULL;
    else GetOCSPBasicRes(basic_resp, bs); /* NO NEED TO DUP */
    if(!(res = OCSP_response_create(st, bs)))
        ossl_raise(eOCSPError, NULL);
    WrapOCSPRes(klass, obj, res);

    return obj;
}
new(p1 = v1) click to toggle source
static VALUE
ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE arg;
    const unsigned char *p;

    rb_scan_args(argc, argv, "01", &arg);
    if(!NIL_P(arg)){
        OCSP_RESPONSE *res = DATA_PTR(self), *x;
        arg = ossl_to_der_if_possible(arg);
        StringValue(arg);
        p = (unsigned char *)RSTRING_PTR(arg);
        x = d2i_OCSP_RESPONSE(&res, &p, RSTRING_LEN(arg));
        DATA_PTR(self) = res;
        if(!x){
            ossl_raise(eOCSPError, "cannot load DER encoded response");
        }
    }

    return self;
}

Public Instance Methods

basic() click to toggle source
static VALUE
ossl_ocspres_get_basic(VALUE self)
{
    OCSP_RESPONSE *res;
    OCSP_BASICRESP *bs;
    VALUE ret;

    GetOCSPRes(self, res);
    if(!(bs = OCSP_response_get1_basic(res)))
        return Qnil;
    WrapOCSPBasicRes(cOCSPBasicRes, ret, bs);

    return ret;
}
status() click to toggle source
static VALUE
ossl_ocspres_status(VALUE self)
{
    OCSP_RESPONSE *res;
    int st;

    GetOCSPRes(self, res);
    st = OCSP_response_status(res);

    return INT2NUM(st);
}
status_string() click to toggle source
static VALUE
ossl_ocspres_status_string(VALUE self)
{
    OCSP_RESPONSE *res;
    int st;

    GetOCSPRes(self, res);
    st = OCSP_response_status(res);

    return rb_str_new2(OCSP_response_status_str(st));
}
to_der() click to toggle source
static VALUE
ossl_ocspres_to_der(VALUE self)
{
    OCSP_RESPONSE *res;
    VALUE str;
    long len;
    unsigned char *p;

    GetOCSPRes(self, res);
    if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0)
        ossl_raise(eOCSPError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_OCSP_RESPONSE(res, &p) <= 0)
        ossl_raise(eOCSPError, NULL);
    ossl_str_adjust(str, p);

    return str;
}


class OpenSSL::OpenSSLError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::OpenSSLError

Generic error, common for all classes under OpenSSL module

In Files

  • ext/openssl/ossl.c

Parent

StandardError


class OpenSSL::PKCS12 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKCS12

Defines a file format commonly used to store private keys with accompanying public key certificates, protected with a password-based symmetric key.

In Files

  • ext/openssl/ossl.c

Parent

Object

Attributes

ca_certs[R]
certificate[R]
key[R]

Public Class Methods

create(pass, name, key, cert [, ca, [, key_pbe [, cert_pbe [, key_iter [, mac_iter [, keytype]]]]]]) click to toggle source

Parameters

  • pass - string

  • name - A string describing the key.

  • key - Any PKey.

  • cert - A X509::Certificate.

    • The public_key portion of the certificate must contain a valid public key.

    • The not_before and not_after fields must be filled in.

  • ca - An optional array of X509::Certificate's.

  • key_pbe - string

  • cert_pbe - string

  • key_iter - integer

  • mac_iter - integer

  • keytype - An integer representing an MSIE specific extension.

Any optional arguments may be supplied as nil to preserve the OpenSSL defaults.

See the OpenSSL documentation for PKCS12_create().

static VALUE
ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
{
    VALUE pass, name, pkey, cert, ca, key_nid, cert_nid, key_iter, mac_iter, keytype;
    VALUE obj;
    char *passphrase, *friendlyname;
    EVP_PKEY *key;
    X509 *x509;
    STACK_OF(X509) *x509s;
    int nkey = 0, ncert = 0, kiter = 0, miter = 0, ktype = 0;
    PKCS12 *p12;

    rb_scan_args(argc, argv, "46", &pass, &name, &pkey, &cert, &ca, &key_nid, &cert_nid, &key_iter, &mac_iter, &keytype);
    passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
    friendlyname = NIL_P(name) ? NULL : StringValuePtr(name);
    key = GetPKeyPtr(pkey);
    x509 = GetX509CertPtr(cert);
    x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca);
/* TODO: make a VALUE to nid function */
    if (!NIL_P(key_nid)) {
        if ((nkey = OBJ_txt2nid(StringValuePtr(key_nid))) == NID_undef)
            ossl_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(key_nid));
    }
    if (!NIL_P(cert_nid)) {
        if ((ncert = OBJ_txt2nid(StringValuePtr(cert_nid))) == NID_undef)
            ossl_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(cert_nid));
    }
    if (!NIL_P(key_iter))
        kiter = NUM2INT(key_iter);
    if (!NIL_P(mac_iter))
        miter = NUM2INT(mac_iter);
    if (!NIL_P(keytype))
        ktype = NUM2INT(keytype);

    p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s,
                        nkey, ncert, kiter, miter, ktype);
    sk_X509_pop_free(x509s, X509_free);
    if(!p12) ossl_raise(ePKCS12Error, NULL);
    WrapPKCS12(cPKCS12, obj, p12);

    ossl_pkcs12_set_key(obj, pkey);
    ossl_pkcs12_set_cert(obj, cert);
    ossl_pkcs12_set_ca_certs(obj, ca);

    return obj;
}
new → pkcs12 click to toggle source
new(str) → pkcs12
new(str, pass) → pkcs12

Parameters

  • str - Must be a DER encoded PKCS12 string.

  • pass - string

static VALUE
ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
{
    BIO *in;
    VALUE arg, pass, pkey, cert, ca;
    char *passphrase;
    EVP_PKEY *key;
    X509 *x509;
    STACK_OF(X509) *x509s = NULL;
    int st = 0;
    PKCS12 *pkcs = DATA_PTR(self);

    if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self;
    passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
    in = ossl_obj2bio(arg);
    d2i_PKCS12_bio(in, &pkcs);
    DATA_PTR(self) = pkcs;
    BIO_free(in);

    pkey = cert = ca = Qnil;
    if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s))
        ossl_raise(ePKCS12Error, "PKCS12_parse");
    pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key,
                      &st); /* NO DUP */
    if(st) goto err;
    cert = rb_protect((VALUE(*)_((VALUE)))ossl_x509_new, (VALUE)x509, &st);
    if(st) goto err;
    if(x509s){
        ca =
            rb_protect((VALUE(*)_((VALUE)))ossl_x509_sk2ary, (VALUE)x509s, &st);
        if(st) goto err;
    }

  err:
    X509_free(x509);
    sk_X509_pop_free(x509s, X509_free);
    ossl_pkcs12_set_key(self, pkey);
    ossl_pkcs12_set_cert(self, cert);
    ossl_pkcs12_set_ca_certs(self, ca);
    if(st) rb_jump_tag(st);

    return self;
}

Public Instance Methods

to_der() click to toggle source
static VALUE
ossl_pkcs12_to_der(VALUE self)
{
    PKCS12 *p12;
    VALUE str;
    long len;
    unsigned char *p;

    GetPKCS12(self, p12);
    if((len = i2d_PKCS12(p12, NULL)) <= 0)
        ossl_raise(ePKCS12Error, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_PKCS12(p12, &p) <= 0)
        ossl_raise(ePKCS12Error, NULL);
    ossl_str_adjust(str, p);

    return str;
}


class OpenSSL::PKCS12::PKCS12Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKCS12::PKCS12Error

Defines a file format commonly used to store private keys with accompanying public key certificates, protected with a password-based symmetric key.

In Files

  • ext/openssl/ossl_ns_spki.c

Parent

eOSSLError


module OpenSSL::PKCS5 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::PKCS5

Provides password-based encryption functionality based on PKCS#5. Typically used for securely deriving arbitrary length symmetric keys to be used with an OpenSSL::Cipher from passwords. Another use case is for storing passwords: Due to the ability to tweak the effort of computation by increasing the iteration count, computation can be slowed down artificially in order to render possible attacks infeasible.

PKCS5 offers support for PBKDF2 with an OpenSSL::Digest::SHA1-based HMAC, or an arbitrary Digest if the underlying version of OpenSSL already supports it (>= 0.9.4).

Parameters

Password

Typically an arbitrary String that represents the password to be used for deriving a key.

Salt

Prevents attacks based on dictionaries of common passwords. It is a public value that can be safely stored along with the password (e.g. if PBKDF2 is used for password storage). For maximum security, a fresh, random salt should be generated for each stored password. According to PKCS#5, a salt should be at least 8 bytes long.

Iteration Count

Allows to tweak the length that the actual computation will take. The larger the iteration count, the longer it will take.

Key Length

Specifies the length in bytes of the output that will be generated. Typically, the key length should be larger than or equal to the output length of the underlying digest function, otherwise an attacker could simply try to brute-force the key. According to PKCS#5, security is limited by the output length of the underlying digest function, i.e. security is not improved if a key length strictly larger than the digest output length is chosen. Therefore, when using PKCS5 for password storage, it suffices to store values equal to the digest output length, nothing is gained by storing larger values.

Examples

Generating a 128 bit key for a Cipher (e.g. AES)

pass = "secret"
salt = OpenSSL::Random.random_bytes(16)
iter = 20000
key_len = 16
key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, key_len)

Storing Passwords

pass = "secret"
salt = OpenSSL::Random.random_bytes(16) #store this with the generated value
iter = 20000
digest = OpenSSL::Digest::SHA256.new
len = digest.digest_length
#the final value to be stored
value = OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, iter, len, digest)

Important Note on Checking Passwords

When comparing passwords provided by the user with previously stored values, a common mistake made is comparing the two values using “==”. Typically, “==” short-circuits on evaluation, and is therefore vulnerable to timing attacks. The proper way is to use a method that always takes the same amount of time when comparing two values, thus not leaking any information to potential attackers. To compare two values, the following could be used:

def eql_time_cmp(a, b)
  unless a.length == b.length
    return false
  end
  cmp = b.bytes.to_a
  result = 0
  a.bytes.each_with_index {|c,i|
    result |= c ^ cmp[i]
  }
  result == 0
end

Please note that the premature return in case of differing lengths typically does not leak valuable information - when using PKCS#5, the length of the values to be compared is of fixed size.

In Files

  • ext/openssl/ossl.c

Public Class Methods

pbkdf2_hmac(pass, salt, iter, keylen, digest) → string click to toggle source

Parameters

  • pass - string

  • salt - string - should be at least 8 bytes long.

  • iter - integer - should be greater than 1000. 20000 is better.

  • keylen - integer

  • digest - a string or OpenSSL::Digest object.

Available in OpenSSL 0.9.4.

Digests other than SHA1 may not be supported by other cryptography libraries.

static VALUE
ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen, VALUE digest)
{
    VALUE str;
    const EVP_MD *md;
    int len = NUM2INT(keylen);

    StringValue(pass);
    StringValue(salt);
    md = GetDigestPtr(digest);

    str = rb_str_new(0, len);

    if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LENINT(pass),
                          (unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt),
                          NUM2INT(iter), md, len,
                          (unsigned char *)RSTRING_PTR(str)) != 1)
        ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC");

    return str;
}
pbkdf2_hmac_sha1(pass, salt, iter, keylen) → string click to toggle source

Parameters

  • pass - string

  • salt - string - should be at least 8 bytes long.

  • iter - integer - should be greater than 1000. 20000 is better.

  • keylen - integer

This method is available in almost any version of OpenSSL.

Conforms to rfc2898.

static VALUE
ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen)
{
    VALUE str;
    int len = NUM2INT(keylen);

    StringValue(pass);
    StringValue(salt);

    str = rb_str_new(0, len);

    if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LENINT(pass),
                               (const unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), NUM2INT(iter),
                               len, (unsigned char *)RSTRING_PTR(str)) != 1)
        ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1");

    return str;
}


class OpenSSL::PKCS5::PKCS5Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKCS5::PKCS5Error

Generic Exception class that is raised if an error occurs during a computation.

In Files

  • ext/openssl/ossl_pkcs5.c

Parent

eOSSLError


class OpenSSL::PKCS7 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKCS7

In Files

  • ext/openssl/ossl.c

Parent

Object

Constants

Signer

Attributes

data[R]
error_string[RW]

Public Class Methods

encrypt(certs, data, [, cipher [, flags]]) → pkcs7 click to toggle source
static VALUE
ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass)
{
    VALUE certs, data, cipher, flags;
    STACK_OF(X509) *x509s;
    BIO *in;
    const EVP_CIPHER *ciph;
    int flg, status = 0;
    VALUE ret;
    PKCS7 *p7;

    rb_scan_args(argc, argv, "22", &certs, &data, &cipher, &flags);
    if(NIL_P(cipher)){
#if !defined(OPENSSL_NO_RC2)
        ciph = EVP_rc2_40_cbc();
#elif !defined(OPENSSL_NO_DES)
        ciph = EVP_des_ede3_cbc();
#elif !defined(OPENSSL_NO_RC2)
        ciph = EVP_rc2_40_cbc();
#elif !defined(OPENSSL_NO_AES)
        ciph = EVP_EVP_aes_128_cbc();
#else
        ossl_raise(ePKCS7Error, "Must specify cipher");
#endif

    }
    else ciph = GetCipherPtr(cipher); /* NO NEED TO DUP */
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    in = ossl_obj2bio(data);
    x509s = ossl_protect_x509_ary2sk(certs, &status);
    if(status){
        BIO_free(in);
        rb_jump_tag(status);
    }
    if(!(p7 = PKCS7_encrypt(x509s, in, (EVP_CIPHER*)ciph, flg))){
        BIO_free(in);
        sk_X509_pop_free(x509s, X509_free);
        ossl_raise(ePKCS7Error, NULL);
    }
    BIO_free(in);
    WrapPKCS7(cPKCS7, ret, p7);
    ossl_pkcs7_set_data(ret, data);
    sk_X509_pop_free(x509s, X509_free);

    return ret;
}
new → pkcs7 click to toggle source
new(string) → pkcs7

Many methods in this class aren't documented.

static VALUE
ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
{
    PKCS7 *p7, *pkcs = DATA_PTR(self);
    BIO *in;
    VALUE arg;

    if(rb_scan_args(argc, argv, "01", &arg) == 0)
        return self;
    arg = ossl_to_der_if_possible(arg);
    in = ossl_obj2bio(arg);
    p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL);
    if (!p7) {
        OSSL_BIO_reset(in);
        p7 = d2i_PKCS7_bio(in, &pkcs);
        if (!p7) {
            BIO_free(in);
            PKCS7_free(pkcs);
            DATA_PTR(self) = NULL;
            ossl_raise(rb_eArgError, "Could not parse the PKCS7");
        }
    }
    DATA_PTR(self) = pkcs;
    BIO_free(in);
    ossl_pkcs7_set_data(self, Qnil);
    ossl_pkcs7_set_err_string(self, Qnil);

    return self;
}
read_smime(string) → pkcs7 click to toggle source
static VALUE
ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg)
{
    BIO *in, *out;
    PKCS7 *pkcs7;
    VALUE ret, data;

    in = ossl_obj2bio(arg);
    out = NULL;
    pkcs7 = SMIME_read_PKCS7(in, &out);
    BIO_free(in);
    if(!pkcs7) ossl_raise(ePKCS7Error, NULL);
    data = out ? ossl_membio2str(out) : Qnil;
    WrapPKCS7(cPKCS7, ret, pkcs7);
    ossl_pkcs7_set_data(ret, data);
    ossl_pkcs7_set_err_string(ret, Qnil);

    return ret;
}
sign(cert, key, data, [, certs [, flags]]) → pkcs7 click to toggle source
static VALUE
ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass)
{
    VALUE cert, key, data, certs, flags;
    X509 *x509;
    EVP_PKEY *pkey;
    BIO *in;
    STACK_OF(X509) *x509s;
    int flg, status = 0;
    PKCS7 *pkcs7;
    VALUE ret;

    rb_scan_args(argc, argv, "32", &cert, &key, &data, &certs, &flags);
    x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */
    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    in = ossl_obj2bio(data);
    if(NIL_P(certs)) x509s = NULL;
    else{
        x509s = ossl_protect_x509_ary2sk(certs, &status);
        if(status){
            BIO_free(in);
            rb_jump_tag(status);
        }
    }
    if(!(pkcs7 = PKCS7_sign(x509, pkey, x509s, in, flg))){
        BIO_free(in);
        sk_X509_pop_free(x509s, X509_free);
        ossl_raise(ePKCS7Error, NULL);
    }
    WrapPKCS7(cPKCS7, ret, pkcs7);
    ossl_pkcs7_set_data(ret, data);
    ossl_pkcs7_set_err_string(ret, Qnil);
    BIO_free(in);
    sk_X509_pop_free(x509s, X509_free);

    return ret;
}
write_smime(pkcs7 [, data [, flags]]) → string click to toggle source
static VALUE
ossl_pkcs7_s_write_smime(int argc, VALUE *argv, VALUE klass)
{
    VALUE pkcs7, data, flags;
    BIO *out, *in;
    PKCS7 *p7;
    VALUE str;
    int flg;

    rb_scan_args(argc, argv, "12", &pkcs7, &data, &flags);
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    if(NIL_P(data)) data = ossl_pkcs7_get_data(pkcs7);
    SafeGetPKCS7(pkcs7, p7);
    if(!NIL_P(data) && PKCS7_is_detached(p7))
        flg |= PKCS7_DETACHED;
    in = NIL_P(data) ? NULL : ossl_obj2bio(data);
    if(!(out = BIO_new(BIO_s_mem()))){
        BIO_free(in);
        ossl_raise(ePKCS7Error, NULL);
    }
    if(!SMIME_write_PKCS7(out, p7, in, flg)){
        BIO_free(out);
        BIO_free(in);
        ossl_raise(ePKCS7Error, NULL);
    }
    BIO_free(in);
    str = ossl_membio2str(out);

    return str;
}

Public Instance Methods

add_certificate(p1) click to toggle source
static VALUE
ossl_pkcs7_add_certificate(VALUE self, VALUE cert)
{
    PKCS7 *pkcs7;
    X509 *x509;

    GetPKCS7(self, pkcs7);
    x509 = GetX509CertPtr(cert);  /* NO NEED TO DUP */
    if (!PKCS7_add_certificate(pkcs7, x509)){
        ossl_raise(ePKCS7Error, NULL);
    }

    return self;
}
add_crl(p1) click to toggle source
static VALUE
ossl_pkcs7_add_crl(VALUE self, VALUE crl)
{
    PKCS7 *pkcs7;
    X509_CRL *x509crl;

    GetPKCS7(self, pkcs7); /* NO DUP needed! */
    x509crl = GetX509CRLPtr(crl);
    if (!PKCS7_add_crl(pkcs7, x509crl)) {
        ossl_raise(ePKCS7Error, NULL);
    }

    return self;
}
add_data(p1) click to toggle source
static VALUE
ossl_pkcs7_add_data(VALUE self, VALUE data)
{
    PKCS7 *pkcs7;
    BIO *out, *in;
    char buf[4096];
    int len;

    in = ossl_obj2bio(data);
    GetPKCS7(self, pkcs7);
    if(PKCS7_type_is_signed(pkcs7)){
        if(!PKCS7_content_new(pkcs7, NID_pkcs7_data))
            ossl_raise(ePKCS7Error, NULL);
    }
    if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err;
    for(;;){
        if((len = BIO_read(in, buf, sizeof(buf))) <= 0)
            break;
        if(BIO_write(out, buf, len) != len)
            goto err;
    }
    if(!PKCS7_dataFinal(pkcs7, out)) goto err;
    ossl_pkcs7_set_data(self, Qnil);

 err:
    BIO_free(out);
    BIO_free(in);
    if(ERR_peek_error()){
        ossl_raise(ePKCS7Error, NULL);
    }

    return data;
}
Also aliased as: data=
add_recipient(p1) click to toggle source
static VALUE
ossl_pkcs7_add_recipient(VALUE self, VALUE recip)
{
    PKCS7 *pkcs7;
    PKCS7_RECIP_INFO *ri;

    ri = DupPKCS7RecipientPtr(recip); /* NEED TO DUP */
    GetPKCS7(self, pkcs7);
    if (!PKCS7_add_recipient_info(pkcs7, ri)) {
        PKCS7_RECIP_INFO_free(ri);
        ossl_raise(ePKCS7Error, "Could not add recipient.");
    }

    return self;
}
add_signer(p1) click to toggle source
static VALUE
ossl_pkcs7_add_signer(VALUE self, VALUE signer)
{
    PKCS7 *pkcs7;
    PKCS7_SIGNER_INFO *p7si;

    p7si = DupPKCS7SignerPtr(signer); /* NEED TO DUP */
    GetPKCS7(self, pkcs7);
    if (!PKCS7_add_signer(pkcs7, p7si)) {
        PKCS7_SIGNER_INFO_free(p7si);
        ossl_raise(ePKCS7Error, "Could not add signer.");
    }
    if (PKCS7_type_is_signed(pkcs7)){
        PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
                                   V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));
    }

    return self;
}
certificates() click to toggle source
static VALUE
ossl_pkcs7_get_certificates(VALUE self)
{
    return ossl_x509_sk2ary(pkcs7_get_certs(self));
}
certificates=(p1) click to toggle source
static VALUE
ossl_pkcs7_set_certificates(VALUE self, VALUE ary)
{
    STACK_OF(X509) *certs;
    X509 *cert;

    certs = pkcs7_get_certs(self);
    while((cert = sk_X509_pop(certs))) X509_free(cert);
    rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_certs_i, self);

    return ary;
}
cipher=(p1) click to toggle source
static VALUE
ossl_pkcs7_set_cipher(VALUE self, VALUE cipher)
{
    PKCS7 *pkcs7;

    GetPKCS7(self, pkcs7);
    if (!PKCS7_set_cipher(pkcs7, GetCipherPtr(cipher))) {
        ossl_raise(ePKCS7Error, NULL);
    }

    return cipher;
}
crls() click to toggle source
static VALUE
ossl_pkcs7_get_crls(VALUE self)
{
    return ossl_x509crl_sk2ary(pkcs7_get_crls(self));
}
crls=(p1) click to toggle source
static VALUE
ossl_pkcs7_set_crls(VALUE self, VALUE ary)
{
    STACK_OF(X509_CRL) *crls;
    X509_CRL *crl;

    crls = pkcs7_get_crls(self);
    while((crl = sk_X509_CRL_pop(crls))) X509_CRL_free(crl);
    rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_crls_i, self);

    return ary;
}
data=(p1) click to toggle source
Alias for: add_data
decrypt(p1, p2, p3 = v3) click to toggle source
static VALUE
ossl_pkcs7_decrypt(int argc, VALUE *argv, VALUE self)
{
    VALUE pkey, cert, flags;
    EVP_PKEY *key;
    X509 *x509;
    int flg;
    PKCS7 *p7;
    BIO *out;
    VALUE str;

    rb_scan_args(argc, argv, "21", &pkey, &cert, &flags);
    key = GetPrivPKeyPtr(pkey); /* NO NEED TO DUP */
    x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    GetPKCS7(self, p7);
    if(!(out = BIO_new(BIO_s_mem())))
        ossl_raise(ePKCS7Error, NULL);
    if(!PKCS7_decrypt(p7, key, x509, out, flg)){
        BIO_free(out);
        ossl_raise(ePKCS7Error, NULL);
    }
    str = ossl_membio2str(out); /* out will be free */

    return str;
}
detached() click to toggle source
static VALUE
ossl_pkcs7_get_detached(VALUE self)
{
    PKCS7 *p7;
    GetPKCS7(self, p7);
    return PKCS7_get_detached(p7) ? Qtrue : Qfalse;
}
detached=(p1) click to toggle source
static VALUE
ossl_pkcs7_set_detached(VALUE self, VALUE flag)
{
    PKCS7 *p7;

    GetPKCS7(self, p7);
    if(flag != Qtrue && flag != Qfalse)
        ossl_raise(ePKCS7Error, "must specify a boolean");
    if(!PKCS7_set_detached(p7, flag == Qtrue ? 1 : 0))
        ossl_raise(ePKCS7Error, NULL);

    return flag;
}
detached?() click to toggle source
static VALUE
ossl_pkcs7_detached_p(VALUE self)
{
    PKCS7 *p7;
    GetPKCS7(self, p7);
    return PKCS7_is_detached(p7) ? Qtrue : Qfalse;
}
recipients() click to toggle source
static VALUE
ossl_pkcs7_get_recipient(VALUE self)
{
    PKCS7 *pkcs7;
    STACK_OF(PKCS7_RECIP_INFO) *sk;
    PKCS7_RECIP_INFO *si;
    int num, i;
    VALUE ary;

    GetPKCS7(self, pkcs7);
    if (PKCS7_type_is_enveloped(pkcs7))
        sk = pkcs7->d.enveloped->recipientinfo;
    else if (PKCS7_type_is_signedAndEnveloped(pkcs7))
        sk = pkcs7->d.signed_and_enveloped->recipientinfo;
    else sk = NULL;
    if (!sk) return rb_ary_new();
    if ((num = sk_PKCS7_RECIP_INFO_num(sk)) < 0) {
        ossl_raise(ePKCS7Error, "Negative number of recipient!");
    }
    ary = rb_ary_new2(num);
    for (i=0; i<num; i++) {
        si = sk_PKCS7_RECIP_INFO_value(sk, i);
        rb_ary_push(ary, ossl_pkcs7ri_new(si));
    }

    return ary;
}
signers() click to toggle source
static VALUE
ossl_pkcs7_get_signer(VALUE self)
{
    PKCS7 *pkcs7;
    STACK_OF(PKCS7_SIGNER_INFO) *sk;
    PKCS7_SIGNER_INFO *si;
    int num, i;
    VALUE ary;

    GetPKCS7(self, pkcs7);
    if (!(sk = PKCS7_get_signer_info(pkcs7))) {
        OSSL_Debug("OpenSSL::PKCS7#get_signer_info == NULL!");
        return rb_ary_new();
    }
    if ((num = sk_PKCS7_SIGNER_INFO_num(sk)) < 0) {
        ossl_raise(ePKCS7Error, "Negative number of signers!");
    }
    ary = rb_ary_new2(num);
    for (i=0; i<num; i++) {
        si = sk_PKCS7_SIGNER_INFO_value(sk, i);
        rb_ary_push(ary, ossl_pkcs7si_new(si));
    }

    return ary;
}
to_der() click to toggle source
static VALUE
ossl_pkcs7_to_der(VALUE self)
{
    PKCS7 *pkcs7;
    VALUE str;
    long len;
    unsigned char *p;

    GetPKCS7(self, pkcs7);
    if((len = i2d_PKCS7(pkcs7, NULL)) <= 0)
        ossl_raise(ePKCS7Error, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_PKCS7(pkcs7, &p) <= 0)
        ossl_raise(ePKCS7Error, NULL);
    ossl_str_adjust(str, p);

    return str;
}
to_pem() click to toggle source
static VALUE
ossl_pkcs7_to_pem(VALUE self)
{
    PKCS7 *pkcs7;
    BIO *out;
    VALUE str;

    GetPKCS7(self, pkcs7);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(ePKCS7Error, NULL);
    }
    if (!PEM_write_bio_PKCS7(out, pkcs7)) {
        BIO_free(out);
        ossl_raise(ePKCS7Error, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}
Also aliased as: to_s
to_s() click to toggle source
Alias for: to_pem
type → string or nil click to toggle source
static VALUE
ossl_pkcs7_get_type(VALUE self)
{
    PKCS7 *p7;

    GetPKCS7(self, p7);
    if(PKCS7_type_is_signed(p7))
        return ID2SYM(rb_intern("signed"));
    if(PKCS7_type_is_encrypted(p7))
        return ID2SYM(rb_intern("encrypted"));
    if(PKCS7_type_is_enveloped(p7))
        return ID2SYM(rb_intern("enveloped"));
    if(PKCS7_type_is_signedAndEnveloped(p7))
        return ID2SYM(rb_intern("signedAndEnveloped"));
    if(PKCS7_type_is_data(p7))
        return ID2SYM(rb_intern("data"));
    return Qnil;
}
type = type → type click to toggle source
static VALUE
ossl_pkcs7_set_type(VALUE self, VALUE type)
{
    PKCS7 *p7;

    GetPKCS7(self, p7);
    if(!PKCS7_set_type(p7, ossl_pkcs7_sym2typeid(type)))
        ossl_raise(ePKCS7Error, NULL);

    return type;
}
verify(p1, p2, p3 = v3, p4 = v4) click to toggle source
static VALUE
ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)
{
    VALUE certs, store, indata, flags;
    STACK_OF(X509) *x509s;
    X509_STORE *x509st;
    int flg, ok, status = 0;
    BIO *in, *out;
    PKCS7 *p7;
    VALUE data;
    const char *msg;

    rb_scan_args(argc, argv, "22", &certs, &store, &indata, &flags);
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    if(NIL_P(indata)) indata = ossl_pkcs7_get_data(self);
    in = NIL_P(indata) ? NULL : ossl_obj2bio(indata);
    if(NIL_P(certs)) x509s = NULL;
    else{
        x509s = ossl_protect_x509_ary2sk(certs, &status);
        if(status){
            BIO_free(in);
            rb_jump_tag(status);
        }
    }
    x509st = GetX509StorePtr(store);
    GetPKCS7(self, p7);
    if(!(out = BIO_new(BIO_s_mem()))){
        BIO_free(in);
        sk_X509_pop_free(x509s, X509_free);
        ossl_raise(ePKCS7Error, NULL);
    }
    ok = PKCS7_verify(p7, x509s, x509st, in, out, flg);
    BIO_free(in);
    if (ok < 0) ossl_raise(ePKCS7Error, NULL);
    msg = ERR_reason_error_string(ERR_get_error());
    ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil);
    ERR_clear_error();
    data = ossl_membio2str(out);
    ossl_pkcs7_set_data(self, data);
    sk_X509_pop_free(x509s, X509_free);

    return (ok == 1) ? Qtrue : Qfalse;
}


class OpenSSL::PKCS7::PKCS7Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKCS7::PKCS7Error

In Files

  • ext/openssl/ossl_pkcs5.c

Parent

eOSSLError


class OpenSSL::PKCS7::RecipientInfo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKCS7::RecipientInfo

In Files

  • ext/openssl/ossl_pkcs5.c

Parent

Object

Public Class Methods

new(p1) click to toggle source
static VALUE
ossl_pkcs7ri_initialize(VALUE self, VALUE cert)
{
    PKCS7_RECIP_INFO *p7ri;
    X509 *x509;

    x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */
    GetPKCS7ri(self, p7ri);
    if (!PKCS7_RECIP_INFO_set(p7ri, x509)) {
        ossl_raise(ePKCS7Error, NULL);
    }

    return self;
}

Public Instance Methods

enc_key() click to toggle source
static VALUE
ossl_pkcs7ri_get_enc_key(VALUE self)
{
    PKCS7_RECIP_INFO *p7ri;

    GetPKCS7ri(self, p7ri);

    return asn1str_to_str(p7ri->enc_key);
}
issuer() click to toggle source
static VALUE
ossl_pkcs7ri_get_issuer(VALUE self)
{
    PKCS7_RECIP_INFO *p7ri;

    GetPKCS7ri(self, p7ri);

    return ossl_x509name_new(p7ri->issuer_and_serial->issuer);
}
serial() click to toggle source
static VALUE
ossl_pkcs7ri_get_serial(VALUE self)
{
    PKCS7_RECIP_INFO *p7ri;

    GetPKCS7ri(self, p7ri);

    return asn1integer_to_num(p7ri->issuer_and_serial->serial);
}


class OpenSSL::PKCS7::SignerInfo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKCS7::SignerInfo

In Files

  • ext/openssl/ossl_pkcs5.c

Parent

Object

Public Class Methods

new(p1, p2, p3) click to toggle source
static VALUE
ossl_pkcs7si_initialize(VALUE self, VALUE cert, VALUE key, VALUE digest)
{
    PKCS7_SIGNER_INFO *p7si;
    EVP_PKEY *pkey;
    X509 *x509;
    const EVP_MD *md;

    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
    x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */
    md = GetDigestPtr(digest);
    GetPKCS7si(self, p7si);
    if (!(PKCS7_SIGNER_INFO_set(p7si, x509, pkey, (EVP_MD*)md))) {
        ossl_raise(ePKCS7Error, NULL);
    }

    return self;
}

Public Instance Methods

issuer() click to toggle source
static VALUE
ossl_pkcs7si_get_issuer(VALUE self)
{
    PKCS7_SIGNER_INFO *p7si;

    GetPKCS7si(self, p7si);

    return ossl_x509name_new(p7si->issuer_and_serial->issuer);
}
Also aliased as: name
name() click to toggle source
Alias for: issuer
serial() click to toggle source
static VALUE
ossl_pkcs7si_get_serial(VALUE self)
{
    PKCS7_SIGNER_INFO *p7si;

    GetPKCS7si(self, p7si);

    return asn1integer_to_num(p7si->issuer_and_serial->serial);
}
signed_time() click to toggle source
static VALUE
ossl_pkcs7si_get_signed_time(VALUE self)
{
    PKCS7_SIGNER_INFO *p7si;
    ASN1_TYPE *asn1obj;

    GetPKCS7si(self, p7si);

    if (!(asn1obj = PKCS7_get_signed_attribute(p7si, NID_pkcs9_signingTime))) {
        ossl_raise(ePKCS7Error, NULL);
    }
    if (asn1obj->type == V_ASN1_UTCTIME) {
        return asn1time_to_time(asn1obj->value.utctime);
    }
    /*
     * OR
     * ossl_raise(ePKCS7Error, "...");
     * ?
     */

    return Qnil;
}


module OpenSSL::PKey - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::PKey

Asymmetric Public Key Algorithms

Asymmetric public key algorithms solve the problem of establishing and sharing secret keys to en-/decrypt messages. The key in such an algorithm consists of two parts: a public key that may be distributed to others and a private key that needs to remain secret.

Messages encrypted with a public key can only be encrypted by recipients that are in possession of the associated private key. Since public key algorithms are considerably slower than symmetric key algorithms (cf. OpenSSL::Cipher) they are often used to establish a symmetric key shared between two parties that are in possession of each other's public key.

Asymmetric algorithms offer a lot of nice features that are used in a lot of different areas. A very common application is the creation and validation of digital signatures. To sign a document, the signatory generally uses a message digest algorithm (cf. OpenSSL::Digest) to compute a digest of the document that is then encrypted (i.e. signed) using the private key. Anyone in possession of the public key may then verify the signature by computing the message digest of the original document on their own, decrypting the signature using the signatory's public key and comparing the result to the message digest they previously computed. The signature is valid if and only if the decrypted signature is equal to this message digest.

The PKey module offers support for three popular public/private key algorithms:

  • RSA (OpenSSL::PKey::RSA)

  • DSA (OpenSSL::PKey::DSA)

  • Elliptic Curve Cryptography (OpenSSL::PKey::EC)

Each of these implementations is in fact a sub-class of the abstract PKey class which offers the interface for supporting digital signatures in the form of OpenSSL::PKey::PKey#sign and OpenSSL::PKey::PKey#verify.

Diffie-Hellman Key Exchange

Finally PKey also features OpenSSL::PKey::DH, an implementation of the Diffie-Hellman key exchange protocol based on discrete logarithms in finite fields, the same basis that DSA is built on. The Diffie-Hellman protocol can be used to exchange (symmetric) keys over insecure channels without needing any prior joint knowledge between the participating parties. As the security of DH demands relatively long “public keys” (i.e. the part that is overtly transmitted between participants) DH tends to be quite slow. If security or speed is your primary concern, OpenSSL::PKey::EC offers another implementation of the Diffie-Hellman protocol.

let rdoc know about mOSSL and mPKey

let rdoc know about mOSSL and mPKey

let rdoc know about mOSSL and mPKey

In Files

  • lib/rubygems/security.rb
  • ext/openssl/ossl.c

Public Class Methods

OpenSSL::PKey.read(string [, pwd ] ) → PKey click to toggle source
OpenSSL::PKey.read(file [, pwd ]) → PKey

Parameters

  • string is a DER- or PEM-encoded string containing an arbitrary private

or public key.

  • file is an instance of File containing a DER- or PEM-encoded

arbitrary private or public key.

  • pwd is an optional password in case string or file is an encrypted

PEM resource.

static VALUE
ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
{
     EVP_PKEY *pkey;
     BIO *bio;
     VALUE data, pass;
     char *passwd = NULL;

     rb_scan_args(argc, argv, "11", &data, &pass);

     bio = ossl_obj2bio(data);
     if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
        OSSL_BIO_reset(bio);
        if (!NIL_P(pass)) {
            passwd = StringValuePtr(pass);
        }
        if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, passwd))) {
            OSSL_BIO_reset(bio);
            if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
                OSSL_BIO_reset(bio);
                if (!NIL_P(pass)) {
                    passwd = StringValuePtr(pass);
                }
                pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, passwd);
            }
        }
    }

    BIO_free(bio);
    if (!pkey)
        ossl_raise(rb_eArgError, "Could not parse PKey");
    return ossl_pkey_new(pkey);
}


class OpenSSL::PKey::DH - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::DH

An implementation of the Diffie-Hellman key exchange protocol based on discrete logarithms in finite fields, the same basis that DSA is built on.

Accessor methods for the Diffie-Hellman parameters

  • DH#p

The prime (an OpenSSL::BN) of the Diffie-Hellman parameters.

  • DH#g

The generator (an OpenSSL::BN) g of the Diffie-Hellman parameters.

  • DH#pub_key

The per-session public key (an OpenSSL::BN) matching the private key. This needs to be passed to #compute_key.

  • DH#priv_key

The per-session private key, an OpenSSL::BN.

Example of a key exchange

dh1 = OpenSSL::PKey::DH.new(2048)
der = dh1.public_key.to_der #you may send this publicly to the participating party
dh2 = OpenSSL::PKey::DH.new(der)
dh2.generate_key! #generate the per-session key pair
symm_key1 = dh1.compute_key(dh2.pub_key)
symm_key2 = dh2.compute_key(dh1.pub_key)

puts symm_key1 == symm_key2 # => true

In Files

  • ext/openssl/ossl_pkey.c

Parent

cPKey

Public Class Methods

generate(size [, generator]) → dh click to toggle source

Creates a new DH instance from scratch by generating the private and public components alike.

Parameters

  • size is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.

  • generator is a small number > 1, typically 2 or 5.

static VALUE
ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass)
{
    DH *dh ;
    int g = 2;
    VALUE size, gen, obj;

    if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) {
        g = NUM2INT(gen);
    }
    dh = dh_generate(NUM2INT(size), g);
    obj = dh_instance(klass, dh);
    if (obj == Qfalse) {
        DH_free(dh);
        ossl_raise(eDHError, NULL);
    }

    return obj;
}
new([size [, generator] | string]) → dh click to toggle source

Either generates a DH instance from scratch or by reading already existing DH parameters from string. Note that when reading a DH instance from data that was encoded from a DH instance by using #to_pem or #to_der the result will not contain a public/private key pair yet. This needs to be generated using #generate_key! first.

Parameters

  • size is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.

  • generator is a small number > 1, typically 2 or 5.

  • string contains the DER or PEM encoded key.

Examples

DH.new # -> dh
DH.new(1024) # -> dh
DH.new(1024, 5) # -> dh
#Reading DH parameters
dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet
dh.generate_key! # -> dh with public and private key
static VALUE
ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    DH *dh;
    int g = 2;
    BIO *in;
    VALUE arg, gen;

    GetPKey(self, pkey);
    if(rb_scan_args(argc, argv, "02", &arg, &gen) == 0) {
      dh = DH_new();
    }
    else if (FIXNUM_P(arg)) {
        if (!NIL_P(gen)) {
            g = NUM2INT(gen);
        }
        if (!(dh = dh_generate(FIX2INT(arg), g))) {
            ossl_raise(eDHError, NULL);
        }
    }
    else {
        arg = ossl_to_der_if_possible(arg);
        in = ossl_obj2bio(arg);
        dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
        if (!dh){
            OSSL_BIO_reset(in);
            dh = d2i_DHparams_bio(in, NULL);
        }
        BIO_free(in);
        if (!dh) {
            ossl_raise(eDHError, NULL);
        }
    }
    if (!EVP_PKEY_assign_DH(pkey, dh)) {
        DH_free(dh);
        ossl_raise(eDHError, NULL);
    }
    return self;
}

Public Instance Methods

compute_key(pub_bn) → aString click to toggle source

Returns a String containing a shared secret computed from the other party's public value. See DH_compute_key() for further information.

Parameters

  • pub_bn is a OpenSSL::BN, not the DH instance returned by

#public_key as that contains the DH parameters only.

static VALUE
ossl_dh_compute_key(VALUE self, VALUE pub)
{
    DH *dh;
    EVP_PKEY *pkey;
    BIGNUM *pub_key;
    VALUE str;
    int len;

    GetPKeyDH(self, pkey);
    dh = pkey->pkey.dh;
    pub_key = GetBNPtr(pub);
    len = DH_size(dh);
    str = rb_str_new(0, len);
    if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) {
        ossl_raise(eDHError, NULL);
    }
    rb_str_set_len(str, len);

    return str;
}
to_pem → aString click to toggle source

Encodes this DH to its PEM encoding. Note that any existing per-session public/private keys will not get encoded, just the Diffie-Hellman parameters will be encoded.

static VALUE
ossl_dh_export(VALUE self)
{
    EVP_PKEY *pkey;
    BIO *out;
    VALUE str;

    GetPKeyDH(self, pkey);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eDHError, NULL);
    }
    if (!PEM_write_bio_DHparams(out, pkey->pkey.dh)) {
        BIO_free(out);
        ossl_raise(eDHError, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}
Also aliased as: to_pem, to_s
generate_key! → self click to toggle source

Generates a private and public key unless a private key already exists. If this DH instance was generated from public DH parameters (e.g. by encoding the result of #public_key), then this method needs to be called first in order to generate the per-session keys before performing the actual key exchange.

Example

dh = OpenSSL::PKey::DH.new(2048)
public_key = dh.public_key #contains no private/public key yet
public_key.generate_key!
puts public_key.private? # => true

static VALUE
ossl_dh_generate_key(VALUE self)
{
    DH *dh;
    EVP_PKEY *pkey;

    GetPKeyDH(self, pkey);
    dh = pkey->pkey.dh;

    if (!DH_generate_key(dh))
        ossl_raise(eDHError, "Failed to generate key");
    return self;
}
params → hash click to toggle source

Stores all parameters of key to the hash INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don't use :-)) (I's up to you)

static VALUE
ossl_dh_get_params(VALUE self)
{
    EVP_PKEY *pkey;
    VALUE hash;

    GetPKeyDH(self, pkey);

    hash = rb_hash_new();

    rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dh->p));
    rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dh->g));
    rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dh->pub_key));
    rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dh->priv_key));

    return hash;
}
check_params → true | false click to toggle source

Validates the Diffie-Hellman parameters associated with this instance. It checks whether a safe prime and a suitable generator are used. If this is not the case, false is returned.

static VALUE
ossl_dh_check_params(VALUE self)
{
    DH *dh;
    EVP_PKEY *pkey;
    int codes;

    GetPKeyDH(self, pkey);
    dh = pkey->pkey.dh;

    if (!DH_check(dh, &codes)) {
        return Qfalse;
    }

    return codes == 0 ? Qtrue : Qfalse;
}
private? → true | false click to toggle source

Indicates whether this DH instance has a private key associated with it or not. The private key may be retrieved with DH#priv_key.

static VALUE
ossl_dh_is_private(VALUE self)
{
    EVP_PKEY *pkey;

    GetPKeyDH(self, pkey);

    return (DH_PRIVATE(pkey->pkey.dh)) ? Qtrue : Qfalse;
}
public? → true | false click to toggle source

Indicates whether this DH instance has a public key associated with it or not. The public key may be retrieved with DH#pub_key.

static VALUE
ossl_dh_is_public(VALUE self)
{
    EVP_PKEY *pkey;

    GetPKeyDH(self, pkey);

    return (pkey->pkey.dh->pub_key) ? Qtrue : Qfalse;
}
public_key → aDH click to toggle source

Returns a new DH instance that carries just the public information, i.e. the prime p and the generator g, but no public/private key yet. Such a pair may be generated using #generate_key!. The “public key” needed for a key exchange with #compute_key is considered as per-session information and may be retrieved with DH#pub_key once a key pair has been generated. If the current instance already contains private information (and thus a valid public/private key pair), this information will no longer be present in the new instance generated by #public_key. This feature is helpful for publishing the Diffie-Hellman parameters without leaking any of the private per-session information.

Example

dh = OpenSSL::PKey::DH.new(2048) # has public and private key set
public_key = dh.public_key # contains only prime and generator
parameters = public_key.to_der # it's safe to publish this
static VALUE
ossl_dh_to_public_key(VALUE self)
{
    EVP_PKEY *pkey;
    DH *dh;
    VALUE obj;

    GetPKeyDH(self, pkey);
    dh = DHparams_dup(pkey->pkey.dh); /* err check perfomed by dh_instance */
    obj = dh_instance(CLASS_OF(self), dh);
    if (obj == Qfalse) {
        DH_free(dh);
        ossl_raise(eDHError, NULL);
    }

    return obj;
}
to_der → aString click to toggle source

Encodes this DH to its DER encoding. Note that any existing per-session public/private keys will not get encoded, just the Diffie-Hellman parameters will be encoded.

static VALUE
ossl_dh_to_der(VALUE self)
{
    EVP_PKEY *pkey;
    unsigned char *p;
    long len;
    VALUE str;

    GetPKeyDH(self, pkey);
    if((len = i2d_DHparams(pkey->pkey.dh, NULL)) <= 0)
        ossl_raise(eDHError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_DHparams(pkey->pkey.dh, &p) < 0)
        ossl_raise(eDHError, NULL);
    ossl_str_adjust(str, p);

    return str;
}
to_pem() click to toggle source
Alias for: export
to_s() click to toggle source
Alias for: export
to_text → aString click to toggle source

Prints all parameters of key to buffer INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don't use :-)) (I's up to you)

static VALUE
ossl_dh_to_text(VALUE self)
{
    EVP_PKEY *pkey;
    BIO *out;
    VALUE str;

    GetPKeyDH(self, pkey);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eDHError, NULL);
    }
    if (!DHparams_print(out, pkey->pkey.dh)) {
        BIO_free(out);
        ossl_raise(eDHError, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}


class OpenSSL::PKey::DHError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::DHError

Generic exception that is raised if an operation on a DH PKey fails unexpectedly or in case an instantiation of an instance of DH fails due to non-conformant input data.

In Files

  • ext/openssl/ossl_pkey.c

Parent

ePKeyError


class OpenSSL::PKey::DSA - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::DSA

DSA, the Digital Signature Algorithm, is specified in NIST's FIPS 186-3. It is an asymmetric public key algorithm that may be used similar to e.g. RSA. Please note that for OpenSSL versions prior to 1.0.0 the digest algorithms OpenSSL::Digest::DSS (equivalent to SHA) or OpenSSL::Digest::DSS1 (equivalent to SHA-1) must be used for issuing signatures with a DSA key using OpenSSL::PKey#sign. Starting with OpenSSL 1.0.0, digest algorithms are no longer restricted, any Digest may be used for signing.

In Files

  • ext/openssl/ossl_pkey.c

Parent

cPKey

Public Class Methods

generate(size) → dsa click to toggle source

Creates a new DSA instance by generating a private/public key pair from scratch.

Parameters

  • size is an integer representing the desired key size.

static VALUE
ossl_dsa_s_generate(VALUE klass, VALUE size)
{
    DSA *dsa = dsa_generate(NUM2INT(size)); /* err handled by dsa_instance */
    VALUE obj = dsa_instance(klass, dsa);

    if (obj == Qfalse) {
        DSA_free(dsa);
        ossl_raise(eDSAError, NULL);
    }

    return obj;
}
new([size | string [, pass]) → dsa click to toggle source

Creates a new DSA instance by reading an existing key from string.

Parameters

  • size is an integer representing the desired key size.

  • string contains a DER or PEM encoded key.

  • pass is a string that contains an optional password.

Examples

DSA.new -> dsa
DSA.new(1024) -> dsa
DSA.new(File.read('dsa.pem')) -> dsa
DSA.new(File.read('dsa.pem'), 'mypassword') -> dsa
static VALUE
ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    DSA *dsa;
    BIO *in;
    char *passwd = NULL;
    VALUE arg, pass;

    GetPKey(self, pkey);
    if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
        dsa = DSA_new();
    }
    else if (FIXNUM_P(arg)) {
        if (!(dsa = dsa_generate(FIX2INT(arg)))) {
            ossl_raise(eDSAError, NULL);
        }
    }
    else {
        if (!NIL_P(pass)) passwd = StringValuePtr(pass);
        arg = ossl_to_der_if_possible(arg);
        in = ossl_obj2bio(arg);
        dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
        if (!dsa) {
            OSSL_BIO_reset(in);
            dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
        }
        if (!dsa) {
            OSSL_BIO_reset(in);
            dsa = d2i_DSAPrivateKey_bio(in, NULL);
        }
        if (!dsa) {
            OSSL_BIO_reset(in);
            dsa = d2i_DSA_PUBKEY_bio(in, NULL);
        }
        if (!dsa) {
            OSSL_BIO_reset(in);
            dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
        }
        BIO_free(in);
        if (!dsa) {
            ERR_clear_error();
            ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
        }
    }
    if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
        DSA_free(dsa);
        ossl_raise(eDSAError, NULL);
    }

    return self;
}

Public Instance Methods

to_pem([cipher, password]) → aString click to toggle source

Encodes this DSA to its PEM encoding.

Parameters

  • cipher is an OpenSSL::Cipher.

  • password is a string containing your password.

Examples

DSA.to_pem -> aString
DSA.to_pem(cipher, 'mypassword') -> aString
static VALUE
ossl_dsa_export(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    BIO *out;
    const EVP_CIPHER *ciph = NULL;
    char *passwd = NULL;
    VALUE cipher, pass, str;

    GetPKeyDSA(self, pkey);
    rb_scan_args(argc, argv, "02", &cipher, &pass);
    if (!NIL_P(cipher)) {
        ciph = GetCipherPtr(cipher);
        if (!NIL_P(pass)) {
            StringValue(pass);
            if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
                ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
            passwd = RSTRING_PTR(pass);
        }
    }
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eDSAError, NULL);
    }
    if (DSA_HAS_PRIVATE(pkey->pkey.dsa)) {
        if (!PEM_write_bio_DSAPrivateKey(out, pkey->pkey.dsa, ciph,
                                         NULL, 0, ossl_pem_passwd_cb, passwd)){
            BIO_free(out);
            ossl_raise(eDSAError, NULL);
        }
    } else {
        if (!PEM_write_bio_DSA_PUBKEY(out, pkey->pkey.dsa)) {
            BIO_free(out);
            ossl_raise(eDSAError, NULL);
        }
    }
    str = ossl_membio2str(out);

    return str;
}
Also aliased as: to_pem, to_s
params → hash click to toggle source

Stores all parameters of key to the hash INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don't use :-)) (I's up to you)

static VALUE
ossl_dsa_get_params(VALUE self)
{
    EVP_PKEY *pkey;
    VALUE hash;

    GetPKeyDSA(self, pkey);

    hash = rb_hash_new();

    rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dsa->p));
    rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.dsa->q));
    rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dsa->g));
    rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dsa->pub_key));
    rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dsa->priv_key));

    return hash;
}
private? → true | false click to toggle source

Indicates whether this DSA instance has a private key associated with it or not. The private key may be retrieved with DSA#private_key.

static VALUE
ossl_dsa_is_private(VALUE self)
{
    EVP_PKEY *pkey;

    GetPKeyDSA(self, pkey);

    return (DSA_PRIVATE(self, pkey->pkey.dsa)) ? Qtrue : Qfalse;
}
public? → true | false click to toggle source

Indicates whether this DSA instance has a public key associated with it or not. The public key may be retrieved with #public_key.

static VALUE
ossl_dsa_is_public(VALUE self)
{
    EVP_PKEY *pkey;

    GetPKeyDSA(self, pkey);

    return (pkey->pkey.dsa->pub_key) ? Qtrue : Qfalse;
}
public_key → aDSA click to toggle source

Returns a new DSA instance that carries just the public key information. If the current instance has also private key information, this will no longer be present in the new instance. This feature is helpful for publishing the public key information without leaking any of the private information.

Example

dsa = OpenSSL::PKey::DSA.new(2048) # has public and private information
pub_key = dsa.public_key # has only the public part available
pub_key_der = pub_key.to_der # it's safe to publish this
static VALUE
ossl_dsa_to_public_key(VALUE self)
{
    EVP_PKEY *pkey;
    DSA *dsa;
    VALUE obj;

    GetPKeyDSA(self, pkey);
    /* err check performed by dsa_instance */
    dsa = DSAPublicKey_dup(pkey->pkey.dsa);
    obj = dsa_instance(CLASS_OF(self), dsa);
    if (obj == Qfalse) {
        DSA_free(dsa);
        ossl_raise(eDSAError, NULL);
    }
    return obj;
}
syssign(string) → aString click to toggle source

Computes and returns the DSA signature of string, where string is expected to be an already-computed message digest of the original input data. The signature is issued using the private key of this DSA instance.

Parameters

  • string is a message digest of the original input data to be signed

Example

dsa = OpenSSL::PKey::DSA.new(2048)
doc = "Sign me"
digest = OpenSSL::Digest::SHA1.digest(doc)
sig = dsa.syssign(digest)
static VALUE
ossl_dsa_sign(VALUE self, VALUE data)
{
    EVP_PKEY *pkey;
    unsigned int buf_len;
    VALUE str;

    GetPKeyDSA(self, pkey);
    StringValue(data);
    if (!DSA_PRIVATE(self, pkey->pkey.dsa)) {
        ossl_raise(eDSAError, "Private DSA key needed!");
    }
    str = rb_str_new(0, ossl_dsa_buf_size(pkey));
    if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
                  (unsigned char *)RSTRING_PTR(str),
                  &buf_len, pkey->pkey.dsa)) { /* type is ignored (0) */
        ossl_raise(eDSAError, NULL);
    }
    rb_str_set_len(str, buf_len);

    return str;
}
sysverify(digest, sig) → true | false click to toggle source

Verifies whether the signature is valid given the message digest input. It does so by validating sig using the public key of this DSA instance.

Parameters

  • digest is a message digest of the original input data to be signed

  • sig is a DSA signature value

Example

dsa = OpenSSL::PKey::DSA.new(2048)
doc = "Sign me"
digest = OpenSSL::Digest::SHA1.digest(doc)
sig = dsa.syssign(digest)
puts dsa.sysverify(digest, sig) # => true

static VALUE
ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
{
    EVP_PKEY *pkey;
    int ret;

    GetPKeyDSA(self, pkey);
    StringValue(digest);
    StringValue(sig);
    /* type is ignored (0) */
    ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LENINT(digest),
                     (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey->pkey.dsa);
    if (ret < 0) {
        ossl_raise(eDSAError, NULL);
    }
    else if (ret == 1) {
        return Qtrue;
    }

    return Qfalse;
}
to_der → aString click to toggle source

Encodes this DSA to its DER encoding.

static VALUE
ossl_dsa_to_der(VALUE self)
{
    EVP_PKEY *pkey;
    int (*i2d_func)_((DSA*, unsigned char**));
    unsigned char *p;
    long len;
    VALUE str;

    GetPKeyDSA(self, pkey);
    if(DSA_HAS_PRIVATE(pkey->pkey.dsa))
        i2d_func = (int(*)_((DSA*,unsigned char**)))i2d_DSAPrivateKey;
    else
        i2d_func = i2d_DSA_PUBKEY;
    if((len = i2d_func(pkey->pkey.dsa, NULL)) <= 0)
        ossl_raise(eDSAError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_func(pkey->pkey.dsa, &p) < 0)
        ossl_raise(eDSAError, NULL);
    ossl_str_adjust(str, p);

    return str;
}
to_pem(p1 = v1, p2 = v2) click to toggle source
Alias for: export
to_s(p1 = v1, p2 = v2) click to toggle source
Alias for: export
to_text → aString click to toggle source

Prints all parameters of key to buffer INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don't use :-)) (I's up to you)

static VALUE
ossl_dsa_to_text(VALUE self)
{
    EVP_PKEY *pkey;
    BIO *out;
    VALUE str;

    GetPKeyDSA(self, pkey);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eDSAError, NULL);
    }
    if (!DSA_print(out, pkey->pkey.dsa, 0)) { /* offset = 0 */
        BIO_free(out);
        ossl_raise(eDSAError, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}


class OpenSSL::PKey::DSAError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::DSAError

Generic exception that is raised if an operation on a DSA PKey fails unexpectedly or in case an instantiation of an instance of DSA fails due to non-conformant input data.

In Files

  • ext/openssl/ossl_pkey.c

Parent

ePKeyError


class OpenSSL::PKey::EC - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::EC

In Files

  • ext/openssl/ossl_pkey.c

Parent

cPKey

Constants

NAMED_CURVE

Public Class Methods

builtin_curves → [[name, comment], ...] click to toggle source

See the OpenSSL documentation for EC_builtin_curves()

static VALUE ossl_s_builtin_curves(VALUE self)
{
    EC_builtin_curve *curves = NULL;
    int n;
    int crv_len = rb_long2int(EC_get_builtin_curves(NULL, 0));
    VALUE ary, ret;

    curves = ALLOCA_N(EC_builtin_curve, crv_len);
    if (curves == NULL)
        return Qnil;
    if (!EC_get_builtin_curves(curves, crv_len))
        ossl_raise(rb_eRuntimeError, "EC_get_builtin_curves");

    ret = rb_ary_new2(crv_len);

    for (n = 0; n < crv_len; n++) {
        const char *sname = OBJ_nid2sn(curves[n].nid);
        const char *comment = curves[n].comment;

        ary = rb_ary_new2(2);
        rb_ary_push(ary, rb_str_new2(sname));
        rb_ary_push(ary, comment ? rb_str_new2(comment) : Qnil);
        rb_ary_push(ret, ary);
    }

    return ret;
}
OpenSSL::PKey::EC.new() click to toggle source
OpenSSL::PKey::EC.new(ec_key)
OpenSSL::PKey::EC.new(ec_group)
OpenSSL::PKey::EC.new("secp112r1")
OpenSSL::PKey::EC.new(pem_string)
OpenSSL::PKey::EC.new(pem_string [, pwd])
OpenSSL::PKey::EC.new(der_string)

See the OpenSSL documentation for:

EC_KEY_*
static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    EC_KEY *ec = NULL;
    VALUE arg, pass;
    VALUE group = Qnil;
    char *passwd = NULL;

    GetPKey(self, pkey);
    if (pkey->pkey.ec)
        ossl_raise(eECError, "EC_KEY already initialized");

    rb_scan_args(argc, argv, "02", &arg, &pass);

    if (NIL_P(arg)) {
        ec = EC_KEY_new();
    } else {
        if (rb_obj_is_kind_of(arg, cEC)) {
            EC_KEY *other_ec = NULL;

            SafeRequire_EC_KEY(arg, other_ec);
            ec = EC_KEY_dup(other_ec);
        } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
                ec = EC_KEY_new();
                group = arg;
        } else {
            BIO *in = ossl_obj2bio(arg);

            if (!NIL_P(pass)) {
                passwd = StringValuePtr(pass);
            }
            ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
            if (!ec) {
                OSSL_BIO_reset(in);
                ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd);
            }
            if (!ec) {
                OSSL_BIO_reset(in);
                ec = d2i_ECPrivateKey_bio(in, NULL);
            }
            if (!ec) {
                OSSL_BIO_reset(in);
                ec = d2i_EC_PUBKEY_bio(in, NULL);
            }

            BIO_free(in);

            if (ec == NULL) {
                const char *name = StringValueCStr(arg);
                int nid = OBJ_sn2nid(name);

                (void)ERR_get_error();
                if (nid == NID_undef)
                    ossl_raise(eECError, "unknown curve name (%s)\n", name);

                if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL)
                    ossl_raise(eECError, "unable to create curve (%s)\n", name);

                EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
                EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
            }
        }
    }

    if (ec == NULL)
        ossl_raise(eECError, NULL);

    if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
        EC_KEY_free(ec);
        ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
    }

    rb_iv_set(self, "@group", Qnil);

    if (!NIL_P(group))
        rb_funcall(self, rb_intern("group="), 1, arg);

    return self;
}

Public Instance Methods

check_key → true click to toggle source

Raises an exception if the key is invalid.

See the OpenSSL documentation for EC_KEY_check_key()

static VALUE ossl_ec_key_check_key(VALUE self)
{
    EC_KEY *ec;

    Require_EC_KEY(self, ec);

    if (EC_KEY_check_key(ec) != 1)
        ossl_raise(eECError, "EC_KEY_check_key");

    return Qtrue;
}
dh_compute_key(pubkey) → String click to toggle source

See the OpenSSL documentation for ECDH_compute_key()

static VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey)
{
    EC_KEY *ec;
    EC_POINT *point;
    int buf_len;
    VALUE str;

    Require_EC_KEY(self, ec);
    SafeRequire_EC_POINT(pubkey, point);

/* BUG: need a way to figure out the maximum string size */
    buf_len = 1024;
    str = rb_str_new(0, buf_len);
/* BUG: take KDF as a block */
    buf_len = ECDH_compute_key(RSTRING_PTR(str), buf_len, point, ec, NULL);
    if (buf_len < 0)
         ossl_raise(eECError, "ECDH_compute_key");

    rb_str_resize(str, buf_len);

    return str;
}
dsa_sign_asn1(data) → String click to toggle source

See the OpenSSL documentation for ECDSA_sign()

static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data)
{
    EC_KEY *ec;
    unsigned int buf_len;
    VALUE str;

    Require_EC_KEY(self, ec);
    StringValue(data);

    if (EC_KEY_get0_private_key(ec) == NULL)
        ossl_raise(eECError, "Private EC key needed!");

    str = rb_str_new(0, ECDSA_size(ec) + 16);
    if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1)
         ossl_raise(eECError, "ECDSA_sign");

    rb_str_resize(str, buf_len);

    return str;
}
dsa_verify_asn1(data, sig) → true or false click to toggle source

See the OpenSSL documentation for ECDSA_verify()

static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
{
    EC_KEY *ec;

    Require_EC_KEY(self, ec);
    StringValue(data);
    StringValue(sig);

    switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) {
    case 1:     return Qtrue;
    case 0:     return Qfalse;
    default:    break;
    }

    ossl_raise(eECError, "ECDSA_verify");

    UNREACHABLE;
}
export → String click to toggle source
export(cipher, pass_phrase) → String

Outputs the EC key in PEM encoding. If cipher and pass_phrase are given they will be used to encrypt the key. cipher must be an OpenSSL::Cipher::Cipher instance. Note that encryption will only be effective for a private key, public keys will always be encoded in plain text.

static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
{
    VALUE cipher, passwd;
    rb_scan_args(argc, argv, "02", &cipher, &passwd);
    return ossl_ec_key_to_string(self, cipher, passwd, EXPORT_PEM);
}
Also aliased as: to_pem
generate_key → self click to toggle source

See the OpenSSL documentation for EC_KEY_generate_key()

static VALUE ossl_ec_key_generate_key(VALUE self)
{
    EC_KEY *ec;

    Require_EC_KEY(self, ec);

    if (EC_KEY_generate_key(ec) != 1)
        ossl_raise(eECError, "EC_KEY_generate_key");

    return self;
}
group → group click to toggle source

Returns a constant OpenSSL::EC::Group that is tied to the key. Modifying the returned group can make the key invalid.

static VALUE ossl_ec_key_get_group(VALUE self)
{
    VALUE group_v;
    EC_KEY *ec;
    ossl_ec_group *ec_group;
    EC_GROUP *group;

    Require_EC_KEY(self, ec);

    group_v = rb_iv_get(self, "@group");
    if (!NIL_P(group_v))
        return group_v;

    if ((group = (EC_GROUP *)EC_KEY_get0_group(ec)) != NULL) {
        group_v = rb_obj_alloc(cEC_GROUP);
        SafeGet_ec_group(group_v, ec_group);
        ec_group->group = group;
        ec_group->dont_free = 1;
        rb_iv_set(group_v, "@key", self);
        rb_iv_set(self, "@group", group_v);
        return group_v;
    }

    return Qnil;
}
group = group → group click to toggle source

Returns the same object passed, not the group object associated with the key. If you wish to access the group object tied to the key call key.group after setting the group.

Setting the group will immediately destroy any previously assigned group object. The group is internally copied by OpenSSL. Modifying the original group after assignment will not effect the internal key structure. (your changes may be lost). BE CAREFUL.

EC_KEY_set_group calls EC_GROUP_free(key->group) then EC_GROUP_dup(), not EC_GROUP_copy. This documentation is accurate for OpenSSL 0.9.8b.

static VALUE ossl_ec_key_set_group(VALUE self, VALUE group_v)
{
    VALUE old_group_v;
    EC_KEY *ec;
    EC_GROUP *group;

    Require_EC_KEY(self, ec);
    SafeRequire_EC_GROUP(group_v, group);

    old_group_v = rb_iv_get(self, "@group");
    if (!NIL_P(old_group_v)) {
        ossl_ec_group *old_ec_group;
        SafeGet_ec_group(old_group_v, old_ec_group);

        old_ec_group->group = NULL;
        old_ec_group->dont_free = 0;
        rb_iv_set(old_group_v, "@key", Qnil);
    }

    rb_iv_set(self, "@group", Qnil);

    if (EC_KEY_set_group(ec, group) != 1)
        ossl_raise(eECError, "EC_KEY_set_group");

    return group_v;
}
private_key → OpenSSL::BN click to toggle source

See the OpenSSL documentation for EC_KEY_get0_private_key()

static VALUE ossl_ec_key_get_private_key(VALUE self)
{
    EC_KEY *ec;
    const BIGNUM *bn;

    Require_EC_KEY(self, ec);

    if ((bn = EC_KEY_get0_private_key(ec)) == NULL)
        return Qnil;

    return ossl_bn_new(bn);
}
private_key = openssl_bn click to toggle source

See the OpenSSL documentation for EC_KEY_set_private_key()

static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)
{
    EC_KEY *ec;
    BIGNUM *bn = NULL;

    Require_EC_KEY(self, ec);
    if (!NIL_P(private_key))
        bn = GetBNPtr(private_key);

    switch (EC_KEY_set_private_key(ec, bn)) {
    case 1:
        break;
    case 0:
        if (bn == NULL)
            break;
    default:
        ossl_raise(eECError, "EC_KEY_set_private_key");
    }

    return private_key;
}
private_key? → true or false click to toggle source

Both #public_key? and #private_key? may return false at the same time unlike other PKey classes.

static VALUE ossl_ec_key_is_private_key(VALUE self)
{
    EC_KEY *ec;

    Require_EC_KEY(self, ec);

    return (EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse);
}
public_key → OpenSSL::PKey::EC::Point click to toggle source

See the OpenSSL documentation for EC_KEY_get0_public_key()

static VALUE ossl_ec_key_get_public_key(VALUE self)
{
    EC_KEY *ec;
    const EC_POINT *point;
    VALUE group;

    Require_EC_KEY(self, ec);

    if ((point = EC_KEY_get0_public_key(ec)) == NULL)
        return Qnil;

    group = rb_funcall(self, rb_intern("group"), 0);
    if (NIL_P(group))
        ossl_raise(eECError, "EC_KEY_get0_get0_group (has public_key but no group???");

    return ossl_ec_point_dup(point, group);
}
public_key = ec_point click to toggle source

See the OpenSSL documentation for EC_KEY_set_public_key()

static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
{
    EC_KEY *ec;
    EC_POINT *point = NULL;

    Require_EC_KEY(self, ec);
    if (!NIL_P(public_key))
        SafeRequire_EC_POINT(public_key, point);

    switch (EC_KEY_set_public_key(ec, point)) {
    case 1:
        break;
    case 0:
        if (point == NULL)
            break;
    default:
        ossl_raise(eECError, "EC_KEY_set_public_key");
    }

    return public_key;
}
public_key? → true or false click to toggle source

Both #public_key? and #private_key? may return false at the same time unlike other PKey classes.

static VALUE ossl_ec_key_is_public_key(VALUE self)
{
    EC_KEY *ec;

    Require_EC_KEY(self, ec);

    return (EC_KEY_get0_public_key(ec) ? Qtrue : Qfalse);
}
to_der → String click to toggle source

See the OpenSSL documentation for i2d_ECPrivateKey_bio()

static VALUE ossl_ec_key_to_der(VALUE self)
{
    return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER);
}
to_pem(p1 = v1, p2 = v2) click to toggle source
Alias for: export
to_text → String click to toggle source

See the OpenSSL documentation for EC_KEY_print()

static VALUE ossl_ec_key_to_text(VALUE self)
{
    EC_KEY *ec;
    BIO *out;
    VALUE str;

    Require_EC_KEY(self, ec);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eECError, "BIO_new(BIO_s_mem())");
    }
    if (!EC_KEY_print(out, ec, 0)) {
        BIO_free(out);
        ossl_raise(eECError, "EC_KEY_print");
    }
    str = ossl_membio2str(out);

    return str;
}


class OpenSSL::PKey::EC::Group - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::EC::Group

In Files

  • ext/openssl/ossl_pkey_ec.c

Parent

Object

Public Class Methods

OpenSSL::PKey::EC::Group.new("secp112r1") click to toggle source
OpenSSL::PKey::EC::Group.new(ec_group)
OpenSSL::PKey::EC::Group.new(pem_string)
OpenSSL::PKey::EC::Group.new(der_string)
OpenSSL::PKey::EC::Group.new(pem_file)
OpenSSL::PKey::EC::Group.new(der_file)
OpenSSL::PKey::EC::Group.new(:GFp_simple)
OpenSSL::PKey::EC::Group.new(:GFp_mult)
OpenSSL::PKey::EC::Group.new(:GFp_nist)
OpenSSL::PKey::EC::Group.new(:GF2m_simple)
OpenSSL::PKey::EC::Group.new(:GFp, bignum_p, bignum_a, bignum_b)
OpenSSL::PKey::EC::Group.new(:GF2m, bignum_p, bignum_a, bignum_b)

See the OpenSSL documentation for EC_GROUP_*

static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE arg1, arg2, arg3, arg4;
    ossl_ec_group *ec_group;
    EC_GROUP *group = NULL;

    Data_Get_Struct(self, ossl_ec_group, ec_group);
    if (ec_group->group != NULL)
        ossl_raise(rb_eRuntimeError, "EC_GROUP is already initialized");

    switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) {
    case 1:
        if (SYMBOL_P(arg1)) {
            const EC_METHOD *method = NULL;
            ID id = SYM2ID(arg1);

            if (id == s_GFp_simple) {
                method = EC_GFp_simple_method();
            } else if (id == s_GFp_mont) {
                method = EC_GFp_mont_method();
            } else if (id == s_GFp_nist) {
                method = EC_GFp_nist_method();
#if !defined(OPENSSL_NO_EC2M)
            } else if (id == s_GF2m_simple) {
                method = EC_GF2m_simple_method();
#endif
            }

            if (method) {
                if ((group = EC_GROUP_new(method)) == NULL)
                    ossl_raise(eEC_GROUP, "EC_GROUP_new");
            } else {
                ossl_raise(rb_eArgError, "unknown symbol, must be :GFp_simple, :GFp_mont, :GFp_nist or :GF2m_simple");
            }
        } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
            const EC_GROUP *arg1_group;

            SafeRequire_EC_GROUP(arg1, arg1_group);
            if ((group = EC_GROUP_dup(arg1_group)) == NULL)
                ossl_raise(eEC_GROUP, "EC_GROUP_dup");
        } else {
            BIO *in = ossl_obj2bio(arg1);

            group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
            if (!group) {
                OSSL_BIO_reset(in);
                group = d2i_ECPKParameters_bio(in, NULL);
            }

            BIO_free(in);

            if (!group) {
                const char *name = StringValueCStr(arg1);
                int nid = OBJ_sn2nid(name);

                (void)ERR_get_error();
                if (nid == NID_undef)
                    ossl_raise(eEC_GROUP, "unknown curve name (%s)", name);

                group = EC_GROUP_new_by_curve_name(nid);
                if (group == NULL)
                    ossl_raise(eEC_GROUP, "unable to create curve (%s)", name);

                EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
                EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
            }
        }

        break;
    case 4:
        if (SYMBOL_P(arg1)) {
            ID id = SYM2ID(arg1);
            EC_GROUP *(*new_curve)(const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL;
            const BIGNUM *p = GetBNPtr(arg2);
            const BIGNUM *a = GetBNPtr(arg3);
            const BIGNUM *b = GetBNPtr(arg4);

            if (id == s_GFp) {
                new_curve = EC_GROUP_new_curve_GFp;
#if !defined(OPENSSL_NO_EC2M)
            } else if (id == s_GF2m) {
                new_curve = EC_GROUP_new_curve_GF2m;
#endif
            } else {
                ossl_raise(rb_eArgError, "unknown symbol, must be :GFp or :GF2m");
            }

            if ((group = new_curve(p, a, b, ossl_bn_ctx)) == NULL)
                ossl_raise(eEC_GROUP, "EC_GROUP_new_by_GF*");
        } else {
             ossl_raise(rb_eArgError, "unknown argument, must be :GFp or :GF2m");
        }

        break;
    default:
        ossl_raise(rb_eArgError, "wrong number of arguments");
    }

    if (group == NULL)
        ossl_raise(eEC_GROUP, "");

    ec_group->group = group;

    return self;
}

Public Instance Methods

==(p1) click to toggle source
Alias for: eql?
asn1_flag → Fixnum click to toggle source

See the OpenSSL documentation for EC_GROUP_get_asn1_flag()

static VALUE ossl_ec_group_get_asn1_flag(VALUE self)
{
    EC_GROUP *group = NULL;
    int flag;

    Require_EC_GROUP(self, group);

    flag = EC_GROUP_get_asn1_flag(group);

    return INT2FIX(flag);
}
asn1_flag = Fixnum → Fixnum click to toggle source

See the OpenSSL documentation for EC_GROUP_set_asn1_flag()

static VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v)
{
    EC_GROUP *group = NULL;

    Require_EC_GROUP(self, group);

    EC_GROUP_set_asn1_flag(group, NUM2INT(flag_v));

    return flag_v;
}
get_cofactor → cofactor_bn click to toggle source

See the OpenSSL documentation for EC_GROUP_get_cofactor()

static VALUE ossl_ec_group_get_cofactor(VALUE self)
{
    VALUE bn_obj;
    BIGNUM *bn;
    EC_GROUP *group = NULL;

    Require_EC_GROUP(self, group);

    bn_obj = ossl_bn_new(NULL);
    bn = GetBNPtr(bn_obj);

    if (EC_GROUP_get_cofactor(group, bn, ossl_bn_ctx) != 1)
        ossl_raise(eEC_GROUP, "EC_GROUP_get_cofactor");

    return bn_obj;
}
curve_name → String click to toggle source

See the OpenSSL documentation for EC_GROUP_get_curve_name()

static VALUE ossl_ec_group_get_curve_name(VALUE self)
{
    EC_GROUP *group = NULL;
    int nid;

    Get_EC_GROUP(self, group);
    if (group == NULL)
        return Qnil;

    nid = EC_GROUP_get_curve_name(group);

/* BUG: an nid or asn1 object should be returned, maybe. */
    return rb_str_new2(OBJ_nid2sn(nid));
}
degree → Fixnum click to toggle source

See the OpenSSL documentation for EC_GROUP_get_degree()

static VALUE ossl_ec_group_get_degree(VALUE self)
{
    EC_GROUP *group = NULL;

    Require_EC_GROUP(self, group);

    return INT2NUM(EC_GROUP_get_degree(group));
}
group1 == group2 → true | false click to toggle source
static VALUE ossl_ec_group_eql(VALUE a, VALUE b)
{
    EC_GROUP *group1 = NULL, *group2 = NULL;

    Require_EC_GROUP(a, group1);
    SafeRequire_EC_GROUP(b, group2);

    if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1)
       return Qfalse;

    return Qtrue;
}
Also aliased as: ==
generator → ec_point click to toggle source

See the OpenSSL documentation for EC_GROUP_get0_generator()

static VALUE ossl_ec_group_get_generator(VALUE self)
{
    VALUE point_obj;
    EC_GROUP *group = NULL;

    Require_EC_GROUP(self, group);

    point_obj = ossl_ec_point_dup(EC_GROUP_get0_generator(group), self);

    return point_obj;
}
get_order → order_bn click to toggle source

See the OpenSSL documentation for EC_GROUP_get_order()

static VALUE ossl_ec_group_get_order(VALUE self)
{
    VALUE bn_obj;
    BIGNUM *bn;
    EC_GROUP *group = NULL;

    Require_EC_GROUP(self, group);

    bn_obj = ossl_bn_new(NULL);
    bn = GetBNPtr(bn_obj);

    if (EC_GROUP_get_order(group, bn, ossl_bn_ctx) != 1)
        ossl_raise(eEC_GROUP, "EC_GROUP_get_order");

    return bn_obj;
}
point_conversion_form → :uncompressed | :compressed | :hybrid click to toggle source

See the OpenSSL documentation for EC_GROUP_get_point_conversion_form()

static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
{
    EC_GROUP *group = NULL;
    point_conversion_form_t form;
    VALUE ret;

    Require_EC_GROUP(self, group);

    form = EC_GROUP_get_point_conversion_form(group);

    switch (form) {
    case POINT_CONVERSION_UNCOMPRESSED: ret = ID_uncompressed; break;
    case POINT_CONVERSION_COMPRESSED:   ret = ID_compressed; break;
    case POINT_CONVERSION_HYBRID:       ret = ID_hybrid; break;
    default:    ossl_raise(eEC_GROUP, "unsupported point conversion form: %d, this module should be updated", form);
    }

   return ID2SYM(ret);
}
point_conversion_form = form → form click to toggle source

See the OpenSSL documentation for EC_GROUP_set_point_conversion_form()

static VALUE ossl_ec_group_set_point_conversion_form(VALUE self, VALUE form_v)
{
    EC_GROUP *group = NULL;
    point_conversion_form_t form;
    ID form_id = SYM2ID(form_v);

    Require_EC_GROUP(self, group);

    if (form_id == ID_uncompressed) {
        form = POINT_CONVERSION_UNCOMPRESSED;
    } else if (form_id == ID_compressed) {
        form = POINT_CONVERSION_COMPRESSED;
    } else if (form_id == ID_hybrid) {
        form = POINT_CONVERSION_HYBRID;
    } else {
        ossl_raise(rb_eArgError, "form must be :compressed, :uncompressed, or :hybrid");
    }

    EC_GROUP_set_point_conversion_form(group, form);

    return form_v;
}
seed → String or nil click to toggle source

See the OpenSSL documentation for EC_GROUP_get0_seed()

static VALUE ossl_ec_group_get_seed(VALUE self)
{
    EC_GROUP *group = NULL;
    size_t seed_len;

    Require_EC_GROUP(self, group);

    seed_len = EC_GROUP_get_seed_len(group);

    if (seed_len == 0)
        return Qnil;

    return rb_str_new((const char *)EC_GROUP_get0_seed(group), seed_len);
}
seed = seed → seed click to toggle source

See the OpenSSL documentation for EC_GROUP_set_seed()

static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed)
{
    EC_GROUP *group = NULL;

    Require_EC_GROUP(self, group);
    StringValue(seed);

    if (EC_GROUP_set_seed(group, (unsigned char *)RSTRING_PTR(seed), RSTRING_LEN(seed)) != (size_t)RSTRING_LEN(seed))
        ossl_raise(eEC_GROUP, "EC_GROUP_set_seed");

    return seed;
}
set_generator(generator, order, cofactor) → self click to toggle source

See the OpenSSL documentation for EC_GROUP_set_generator()

static VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VALUE order, VALUE cofactor)
{
    EC_GROUP *group = NULL;
    const EC_POINT *point;
    const BIGNUM *o, *co;

    Require_EC_GROUP(self, group);
    SafeRequire_EC_POINT(generator, point);
    o = GetBNPtr(order);
    co = GetBNPtr(cofactor);

    if (EC_GROUP_set_generator(group, point, o, co) != 1)
        ossl_raise(eEC_GROUP, "EC_GROUP_set_generator");

    return self;
}
to_der → String click to toggle source

See the OpenSSL documentation for i2d_ECPKParameters_bio()

static VALUE ossl_ec_group_to_der(VALUE self)
{
    return ossl_ec_group_to_string(self, EXPORT_DER);
}
to_pem → String click to toggle source

See the OpenSSL documentation for PEM_write_bio_ECPKParameters()

static VALUE ossl_ec_group_to_pem(VALUE self)
{
    return ossl_ec_group_to_string(self, EXPORT_PEM);
}
to_text → String click to toggle source

See the OpenSSL documentation for ECPKParameters_print()

static VALUE ossl_ec_group_to_text(VALUE self)
{
    EC_GROUP *group;
    BIO *out;
    VALUE str;

    Require_EC_GROUP(self, group);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())");
    }
    if (!ECPKParameters_print(out, group, 0)) {
        BIO_free(out);
        ossl_raise(eEC_GROUP, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}


class OpenSSL::PKey::EC::Group::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::EC::Group::Error

In Files

  • ext/openssl/ossl_pkey_ec.c

Parent

eOSSLError


class OpenSSL::PKey::EC::Point - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::EC::Point

In Files

  • ext/openssl/ossl_pkey_ec.c

Parent

Object

Attributes

group[R]

Public Class Methods

OpenSSL::PKey::EC::Point.new(point) click to toggle source
OpenSSL::PKey::EC::Point.new(group)
OpenSSL::PKey::EC::Point.new(group, bn)

See the OpenSSL documentation for EC_POINT_*

static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
{
    ossl_ec_point *ec_point;
    EC_POINT *point = NULL;
    VALUE arg1, arg2;
    VALUE group_v = Qnil;
    const EC_GROUP *group = NULL;

    Data_Get_Struct(self, ossl_ec_point, ec_point);
    if (ec_point->point)
        ossl_raise(eEC_POINT, "EC_POINT already initialized");

    switch (rb_scan_args(argc, argv, "11", &arg1, &arg2)) {
    case 1:
        if (rb_obj_is_kind_of(arg1, cEC_POINT)) {
            const EC_POINT *arg_point;

            group_v = rb_iv_get(arg1, "@group");
            SafeRequire_EC_GROUP(group_v, group);
            SafeRequire_EC_POINT(arg1, arg_point);

            point = EC_POINT_dup(arg_point, group);
        } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
            group_v = arg1;
            SafeRequire_EC_GROUP(group_v, group);

            point = EC_POINT_new(group);
        } else {
            ossl_raise(eEC_POINT, "wrong argument type: must be OpenSSL::PKey::EC::Point or OpenSSL::Pkey::EC::Group");
        }

        break;
     case 2:
        if (!rb_obj_is_kind_of(arg1, cEC_GROUP))
            ossl_raise(rb_eArgError, "1st argument must be OpenSSL::PKey::EC::Group");
        group_v = arg1;
        SafeRequire_EC_GROUP(group_v, group);

        if (rb_obj_is_kind_of(arg2, cBN)) {
            const BIGNUM *bn = GetBNPtr(arg2);

            point = EC_POINT_bn2point(group, bn, NULL, ossl_bn_ctx);
        } else {
            BIO *in = ossl_obj2bio(arg1);

/* BUG: finish me */

            BIO_free(in);

            if (point == NULL) {
                ossl_raise(eEC_POINT, "unknown type for 2nd arg");
            }
        }
        break;
    default:
        ossl_raise(rb_eArgError, "wrong number of arguments");
    }

    if (point == NULL)
        ossl_raise(eEC_POINT, NULL);

    if (NIL_P(group_v))
        ossl_raise(rb_eRuntimeError, "missing group (internal error)");

    ec_point->point = point;

    rb_iv_set(self, "@group", group_v);

    return self;
}

Public Instance Methods

==(p1) click to toggle source
Alias for: eql?
point1 == point2 → true | false click to toggle source
static VALUE ossl_ec_point_eql(VALUE a, VALUE b)
{
    EC_POINT *point1, *point2;
    VALUE group_v1 = rb_iv_get(a, "@group");
    VALUE group_v2 = rb_iv_get(b, "@group");
    const EC_GROUP *group;

    if (ossl_ec_group_eql(group_v1, group_v2) == Qfalse)
        return Qfalse;

    Require_EC_POINT(a, point1);
    SafeRequire_EC_POINT(b, point2);
    SafeRequire_EC_GROUP(group_v1, group);

    if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1)
        return Qfalse;

    return Qtrue;
}
Also aliased as: ==
infinity? → true | false click to toggle source
static VALUE ossl_ec_point_is_at_infinity(VALUE self)
{
    EC_POINT *point;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, group);

    switch (EC_POINT_is_at_infinity(group, point)) {
    case 1: return Qtrue;
    case 0: return Qfalse;
    default: ossl_raise(cEC_POINT, "EC_POINT_is_at_infinity");
    }

    UNREACHABLE;
}
invert! → self click to toggle source
static VALUE ossl_ec_point_invert(VALUE self)
{
    EC_POINT *point;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, group);

    if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1)
        ossl_raise(cEC_POINT, "EC_POINT_invert");

    return self;
}
make_affine! → self click to toggle source
static VALUE ossl_ec_point_make_affine(VALUE self)
{
    EC_POINT *point;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, group);

    if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)
        ossl_raise(cEC_POINT, "EC_POINT_make_affine");

    return self;
}
mul(bn) → point click to toggle source
mul(bn, bn) → point
mul([bn], [point]) → point
mul([bn], [point], bn) → point
static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
{
    EC_POINT *point1, *point2;
    const EC_GROUP *group;
    VALUE group_v = rb_iv_get(self, "@group");
    VALUE bn_v1, bn_v2, r, points_v;
    BIGNUM *bn1 = NULL, *bn2 = NULL;

    Require_EC_POINT(self, point1);
    SafeRequire_EC_GROUP(group_v, group);

    r = rb_obj_alloc(cEC_POINT);
    ossl_ec_point_initialize(1, &group_v, r);
    Require_EC_POINT(r, point2);

    argc = rb_scan_args(argc, argv, "12", &bn_v1, &points_v, &bn_v2);

    if (rb_obj_is_kind_of(bn_v1, cBN)) {
        bn1 = GetBNPtr(bn_v1);
        if (argc >= 2) {
            bn2 = GetBNPtr(points_v);
        }
        if (EC_POINT_mul(group, point2, bn2, point1, bn1, ossl_bn_ctx) != 1)
            ossl_raise(eEC_POINT, "Multiplication failed");
    } else {
        size_t i, points_len, bignums_len;
        const EC_POINT **points;
        const BIGNUM **bignums;

        Check_Type(bn_v1, T_ARRAY);
        bignums_len = RARRAY_LEN(bn_v1);
        bignums = (const BIGNUM **)OPENSSL_malloc(bignums_len * (int)sizeof(BIGNUM *));

        for (i = 0; i < bignums_len; ++i) {
            bignums[i] = GetBNPtr(rb_ary_entry(bn_v1, i));
        }

        if (!rb_obj_is_kind_of(points_v, rb_cArray)) {
            OPENSSL_free((void *)bignums);
            rb_raise(rb_eTypeError, "Argument2 must be an array");
        }

        rb_ary_unshift(points_v, self);
        points_len = RARRAY_LEN(points_v);
        points = (const EC_POINT **)OPENSSL_malloc(points_len * (int)sizeof(EC_POINT *));

        for (i = 0; i < points_len; ++i) {
            Get_EC_POINT(rb_ary_entry(points_v, i), points[i]);
        }

        if (argc >= 3) {
            bn2 = GetBNPtr(bn_v2);
        }
        if (EC_POINTs_mul(group, point2, bn2, points_len, points, bignums, ossl_bn_ctx) != 1) {
            OPENSSL_free((void *)bignums);
            OPENSSL_free((void *)points);
            ossl_raise(eEC_POINT, "Multiplication failed");
        }
        OPENSSL_free((void *)bignums);
        OPENSSL_free((void *)points);
    }

    return r;
}
on_curve? → true | false click to toggle source
static VALUE ossl_ec_point_is_on_curve(VALUE self)
{
    EC_POINT *point;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, group);

    switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) {
    case 1: return Qtrue;
    case 0: return Qfalse;
    default: ossl_raise(cEC_POINT, "EC_POINT_is_on_curve");
    }

    UNREACHABLE;
}
set_to_infinity! → self click to toggle source
static VALUE ossl_ec_point_set_to_infinity(VALUE self)
{
    EC_POINT *point;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, group);

    if (EC_POINT_set_to_infinity(group, point) != 1)
        ossl_raise(cEC_POINT, "EC_POINT_set_to_infinity");

    return self;
}
to_bn → OpenSSL::BN click to toggle source

See the OpenSSL documentation for EC_POINT_point2bn()

static VALUE ossl_ec_point_to_bn(VALUE self)
{
    EC_POINT *point;
    VALUE bn_obj;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;
    point_conversion_form_t form;
    BIGNUM *bn;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, group);

    form = EC_GROUP_get_point_conversion_form(group);

    bn_obj = rb_obj_alloc(cBN);
    bn = GetBNPtr(bn_obj);

    if (EC_POINT_point2bn(group, point, form, bn, ossl_bn_ctx) == NULL)
        ossl_raise(eEC_POINT, "EC_POINT_point2bn");

    return bn_obj;
}


class OpenSSL::PKey::EC::Point::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::EC::Point::Error

In Files

  • ext/openssl/ossl_pkey_ec.c

Parent

eOSSLError


class OpenSSL::PKey::ECError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::ECError

In Files

  • ext/openssl/ossl_pkey.c

Parent

ePKeyError


class OpenSSL::PKey::PKey - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::PKey

An abstract class that bundles signature creation (#sign) and validation (#verify) that is common to all implementations except OpenSSL::PKey::DH

  • OpenSSL::PKey::RSA

  • OpenSSL::PKey::DSA

  • OpenSSL::PKey::EC

In Files

  • ext/openssl/ossl_pkey.c

Parent

Object

Public Class Methods

new → self click to toggle source

Because PKey is an abstract class, actually calling this method explicitly will raise a NotImplementedError.

static VALUE
ossl_pkey_initialize(VALUE self)
{
    if (rb_obj_is_instance_of(self, cPKey)) {
        ossl_raise(rb_eNotImpError, "OpenSSL::PKey::PKey is an abstract class.");
    }
    return self;
}

Public Instance Methods

sign(digest, data) → String click to toggle source

To sign the String data, digest, an instance of OpenSSL::Digest, must be provided. The return value is again a String containing the signature. A PKeyError is raised should errors occur. Any previous state of the Digest instance is irrelevant to the signature outcome, the digest instance is reset to its initial state during the operation.

Example

data = 'Sign me!'
digest = OpenSSL::Digest::SHA256.new
pkey = OpenSSL::PKey::RSA.new(2048)
signature = pkey.sign(digest, data)
static VALUE
ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
{
    EVP_PKEY *pkey;
    EVP_MD_CTX ctx;
    unsigned int buf_len;
    VALUE str;

    if (rb_funcall(self, id_private_q, 0, NULL) != Qtrue) {
        ossl_raise(rb_eArgError, "Private key is needed.");
    }
    GetPKey(self, pkey);
    EVP_SignInit(&ctx, GetDigestPtr(digest));
    StringValue(data);
    EVP_SignUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
    str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
    if (!EVP_SignFinal(&ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey))
        ossl_raise(ePKeyError, NULL);
    assert((long)buf_len <= RSTRING_LEN(str));
    rb_str_set_len(str, buf_len);

    return str;
}
verify(digest, signature, data) → String click to toggle source

To verify the String signature, digest, an instance of OpenSSL::Digest, must be provided to re-compute the message digest of the original data, also a String. The return value is true if the signature is valid, false otherwise. A PKeyError is raised should errors occur. Any previous state of the Digest instance is irrelevant to the validation outcome, the digest instance is reset to its initial state during the operation.

Example

data = 'Sign me!'
digest = OpenSSL::Digest::SHA256.new
pkey = OpenSSL::PKey::RSA.new(2048)
signature = pkey.sign(digest, data)
pub_key = pkey.public_key
puts pub_key.verify(digest, signature, data) # => true

static VALUE
ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
{
    EVP_PKEY *pkey;
    EVP_MD_CTX ctx;
    int result;

    GetPKey(self, pkey);
    StringValue(sig);
    StringValue(data);
    EVP_VerifyInit(&ctx, GetDigestPtr(digest));
    EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
    result = EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey);
    EVP_MD_CTX_cleanup(&ctx);
    switch (result) {
    case 0:
        return Qfalse;
    case 1:
        return Qtrue;
    default:
        ossl_raise(ePKeyError, NULL);
    }
    return Qnil; /* dummy */
}


class OpenSSL::PKey::PKeyError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::PKeyError

Raised when errors occur during OpenSSL::PKey::PKey#sign or OpenSSL::PKey::PKey#verify.

In Files

  • ext/openssl/ossl_pkey.c

Parent

eOSSLError


class OpenSSL::PKey::RSAError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::PKey::RSAError

Generic exception that is raised if an operation on an RSA PKey fails unexpectedly or in case an instantiation of an instance of RSA fails due to non-conformant input data.

In Files

  • ext/openssl/ossl_pkey.c

Parent

ePKeyError


module OpenSSL::Random - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::Random

In Files

  • ext/openssl/ossl.c


class OpenSSL::Random::RandomError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::Random::RandomError

In Files

  • ext/openssl/ossl_rand.c

Parent

eOSSLError


module OpenSSL::SSL - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::SSL

Use SSLContext to set up the parameters for a TLS (former SSL) connection. Both client and server TLS connections are supported, SSLSocket and SSLServer may be used in conjunction with an instance of SSLContext to set up connections.

let rdoc know about mOSSL

In Files

  • ext/openssl/lib/openssl/ssl.rb
  • ext/openssl/ossl.c

Public Class Methods

verify_certificate_identity(cert, hostname) click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 97
def verify_certificate_identity(cert, hostname)
  should_verify_common_name = true
  cert.extensions.each{|ext|
    next if ext.oid != "subjectAltName"
    ostr = OpenSSL::ASN1.decode(ext.to_der).value.last
    sequence = OpenSSL::ASN1.decode(ostr.value)
    sequence.value.each{|san|
      case san.tag
      when 2 # dNSName in GeneralName (RFC5280)
        should_verify_common_name = false
        reg = Regexp.escape(san.value).gsub(/\\*/, "[^.]+")
        return true if /\A#{reg}\z/ =~ hostname
      when 7 # iPAddress in GeneralName (RFC5280)
        should_verify_common_name = false
        # follows GENERAL_NAME_print() in x509v3/v3_alt.c
        if san.value.size == 4
          return true if san.value.unpack('C*').join('.') == hostname
        elsif san.value.size == 16
          return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname
        end
      end
    }
  }
  if should_verify_common_name
    cert.subject.to_a.each{|oid, value|
      if oid == "CN"
        reg = Regexp.escape(value).gsub(/\\*/, "[^.]+")
        return true if /\A#{reg}\z/ =~ hostname
      end
    }
  end
  return false
end


module OpenSSL::SSL::Nonblock - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::SSL::Nonblock

In Files

  • ext/openssl/lib/openssl/ssl.rb

Public Class Methods

new(*args) click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 89
def initialize(*args)
  flag = File::NONBLOCK
  flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)
  @io.fcntl(Fcntl::F_SETFL, flag)
  super
end


class OpenSSL::SSL::SSLContext - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::SSL::SSLContext

An SSLContext is used to set various options regarding certificates, algorithms, verification, session caching, etc. The SSLContext is used to create an SSLSocket.

All attributes must be set before creating an SSLSocket as the SSLContext will be frozen afterward.

The following attributes are available but don't show up in rdoc:

  • ssl_version, cert, key, #client_ca, #ca_file, #ca_path, timeout,

  • #verify_mode, #verify_depth #client_cert_cb, #tmp_dh_callback,

  • #session_id_context, session_add_cb, #session_new_cb, #session_remove_cb

In Files

  • ext/openssl/lib/openssl/ssl.rb
  • ext/openssl/ossl_ssl.c

Parent

Object

Constants

DEFAULT_CERT_STORE
DEFAULT_PARAMS
METHODS

The list of available SSL/TLS methods

SESSION_CACHE_BOTH

Both client and server sessions are added to the session cache

SESSION_CACHE_CLIENT

Client sessions are added to the session cache

SESSION_CACHE_NO_AUTO_CLEAR

Normally the session cache is checked for expired sessions every 255 connections. Since this may lead to a delay that cannot be controlled, the automatic flushing may be disabled and flush_sessions can be called explicitly.

SESSION_CACHE_NO_INTERNAL

Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and SESSION_CACHE_NO_INTERNAL_STORE.

SESSION_CACHE_NO_INTERNAL_LOOKUP

Always perform external lookups of sessions even if they are in the internal cache.

This flag has no effect on clients

SESSION_CACHE_NO_INTERNAL_STORE

Never automatically store sessions in the internal store.

SESSION_CACHE_OFF

No session caching for client or server

SESSION_CACHE_SERVER

Server sessions are added to the session cache

Attributes

ca_file[RW]

The path to a file containing a PEM-format CA certificate

ca_path[RW]

The path to a directory containing CA certificates in PEM format.

Files are looked up by subject's X509 name's hash value.

cert[RW]

Context certificate

cert_store[RW]

An OpenSSL::X509::Store used for certificate verification

client_ca[RW]

A certificate or Array of certificates that will be sent to the client.

client_cert_cb[RW]

A callback invoked when a client certificate is requested by a server and no certificate has been set.

The callback is invoked with a Session and must return an Array containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any other value is returned the handshake is suspended.

extra_chain_cert[RW]

An Array of extra X509 certificates to be added to the certificate chain.

key[RW]

Context private key

npn_protocols[RW]

An Enumerable of Strings. Each String represents a protocol to be advertised as the list of supported protocols for Next Protocol Negotiation. Supported in OpenSSL 1.0.1 and higher. Has no effect on the client side. If not set explicitly, the NPN extension will not be sent by the server in the handshake.

Example

ctx.npn_protocols = ["http/1.1", "spdy/2"]
npn_select_cb[RW]

A callback invoked on the client side when the client needs to select a protocol from the list sent by the server. Supported in OpenSSL 1.0.1 and higher. The client MUST select a protocol of those advertised by the server. If none is acceptable, raising an error in the callback will cause the handshake to fail. Not setting this callback explicitly means not supporting the NPN extension on the client - any protocols advertised by the server will be ignored.

Example

ctx.npn_select_cb = lambda do |protocols|
  #inspect the protocols and select one
  protocols.first
end
options[RW]

Sets various OpenSSL options.

renegotiation_cb[RW]

A callback invoked whenever a new handshake is initiated. May be used to disable renegotiation entirely.

The callback is invoked with the active SSLSocket. The callback's return value is irrelevant, normal return indicates “approval” of the renegotiation and will continue the process. To forbid renegotiation and to cancel the process, an Error may be raised within the callback.

Disable client renegotiation

When running a server, it is often desirable to disable client renegotiation entirely. You may use a callback as follows to implement this feature:

num_handshakes = 0
ctx.renegotiation_cb = lambda do |ssl|
  num_handshakes += 1
  raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
end
servername_cb[RW]

A callback invoked at connect time to distinguish between multiple server names.

The callback is invoked with an SSLSocket and a server name. The callback must return an SSLContext for the server name or nil.

session_get_cb[RW]

A callback invoked on a server when a session is proposed by the client but the session could not be found in the server's internal cache.

The callback is invoked with the SSLSocket and session id. The callback may return a Session from an external cache.

session_id_context[RW]

Sets the context in which a session can be reused. This allows sessions for multiple applications to be distinguished, for exapmle, by name.

session_new_cb[RW]

A callback invoked when a new session was negotiatied.

The callback is invoked with an SSLSocket. If false is returned the session will be removed from the internal cache.

session_remove_cb[RW]

A callback invoked when a session is removed from the internal cache.

The callback is invoked with an SSLContext and a Session.

ssl_timeout[RW]

Maximum session lifetime.

timeout[RW]

Maximum session lifetime.

tmp_dh_callback[RW]

A callback invoked when DH parameters are required.

The callback is invoked with the Session for the key exchange, an flag indicating the use of an export cipher and the keylength required.

The callback must return an OpenSSL::PKey::DH instance of the correct key length.

verify_callback[RW]

A callback for additional certificate verification. The callback is invoked for each certificate in the chain.

The callback is invoked with two values. preverify_ok indicates indicates if the verification was passed (true) or not (false). store_context is an OpenSSL::X509::StoreContext containing the context used for certificate verification.

If the callback returns false verification is stopped.

verify_depth[RW]

Number of CA certificates to walk when verifying a certificate chain.

verify_mode[RW]

Session verification mode.

Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE, VERIFY_FAIL_IF_NO_PEER_CERT and defined on OpenSSL::SSL

Public Class Methods

new → ctx click to toggle source
new(:TLSv1) → ctx
new("SSLv23_client") → ctx

You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS

static VALUE
ossl_sslctx_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE ssl_method;
    int i;

    for(i = 0; i < numberof(ossl_sslctx_attrs); i++){
        char buf[32];
        snprintf(buf, sizeof(buf), "@%s", ossl_sslctx_attrs[i]);
        rb_iv_set(self, buf, Qnil);
    }
    if (rb_scan_args(argc, argv, "01", &ssl_method) == 0){
        return self;
    }
    ossl_sslctx_set_ssl_version(self, ssl_method);

    return self;
}

Public Instance Methods

ciphers → [[name, version, bits, alg_bits], ...] click to toggle source

The list of ciphers configured for this context.

static VALUE
ossl_sslctx_get_ciphers(VALUE self)
{
    SSL_CTX *ctx;
    STACK_OF(SSL_CIPHER) *ciphers;
    SSL_CIPHER *cipher;
    VALUE ary;
    int i, num;

    Data_Get_Struct(self, SSL_CTX, ctx);
    if(!ctx){
        rb_warning("SSL_CTX is not initialized.");
        return Qnil;
    }
    ciphers = ctx->cipher_list;

    if (!ciphers)
        return rb_ary_new();

    num = sk_SSL_CIPHER_num(ciphers);
    ary = rb_ary_new2(num);
    for(i = 0; i < num; i++){
        cipher = sk_SSL_CIPHER_value(ciphers, i);
        rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher));
    }
    return ary;
}
ciphers = "cipher1:cipher2:..." click to toggle source
ciphers = [name, ...]
ciphers = [[name, version, bits, alg_bits], ...]

Sets the list of available ciphers for this context. Note in a server context some ciphers require the appropriate certificates. For example, an RSA cipher can only be chosen when an RSA certificate is available.

See also OpenSSL::Cipher and OpenSSL::Cipher.ciphers

static VALUE
ossl_sslctx_set_ciphers(VALUE self, VALUE v)
{
    SSL_CTX *ctx;
    VALUE str, elem;
    int i;

    rb_check_frozen(self);
    if (NIL_P(v))
        return v;
    else if (TYPE(v) == T_ARRAY) {
        str = rb_str_new(0, 0);
        for (i = 0; i < RARRAY_LEN(v); i++) {
            elem = rb_ary_entry(v, i);
            if (TYPE(elem) == T_ARRAY) elem = rb_ary_entry(elem, 0);
            elem = rb_String(elem);
            rb_str_append(str, elem);
            if (i < RARRAY_LEN(v)-1) rb_str_cat2(str, ":");
        }
    } else {
        str = v;
        StringValue(str);
    }

    Data_Get_Struct(self, SSL_CTX, ctx);
    if(!ctx){
        ossl_raise(eSSLError, "SSL_CTX is not initialized.");
        return Qnil;
    }
    if (!SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(str))) {
        ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
    }

    return v;
}
flush_sessions(time | nil) → self click to toggle source

Removes sessions in the internal cache that have expired at time.

static VALUE
ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
{
    VALUE arg1;
    SSL_CTX *ctx;
    time_t tm = 0;

    rb_scan_args(argc, argv, "01", &arg1);

    Data_Get_Struct(self, SSL_CTX, ctx);

    if (NIL_P(arg1)) {
        tm = time(0);
    } else if (rb_obj_is_instance_of(arg1, rb_cTime)) {
        tm = NUM2LONG(rb_funcall(arg1, rb_intern("to_i"), 0));
    } else {
        ossl_raise(rb_eArgError, "arg must be Time or nil");
    }

    SSL_CTX_flush_sessions(ctx, (long)tm);

    return self;
}
session_add(session) → true | false click to toggle source

Adds session to the session cache

static VALUE
ossl_sslctx_session_add(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    SSL_SESSION *sess;

    Data_Get_Struct(self, SSL_CTX, ctx);
    SafeGetSSLSession(arg, sess);

    return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse;
}
session_cache_mode → Integer click to toggle source

The current session cache mode.

static VALUE
ossl_sslctx_get_session_cache_mode(VALUE self)
{
    SSL_CTX *ctx;

    Data_Get_Struct(self, SSL_CTX, ctx);

    return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx));
}
session_cache_mode=(integer) → Integer click to toggle source

Sets the SSL session cache mode. Bitwise-or together the desired SESSION_CACHE_* constants to set. See SSL_CTX_set_session_cache_mode(3) for details.

static VALUE
ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;

    Data_Get_Struct(self, SSL_CTX, ctx);

    SSL_CTX_set_session_cache_mode(ctx, NUM2LONG(arg));

    return arg;
}
session_cache_size → Integer click to toggle source

Returns the current session cache size. Zero is used to represent an unlimited cache size.

static VALUE
ossl_sslctx_get_session_cache_size(VALUE self)
{
    SSL_CTX *ctx;

    Data_Get_Struct(self, SSL_CTX, ctx);

    return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx));
}
session_cache_size=(integer) → Integer click to toggle source

Sets the session cache size. Returns the previously valid session cache size. Zero is used to represent an unlimited session cache size.

static VALUE
ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;

    Data_Get_Struct(self, SSL_CTX, ctx);

    SSL_CTX_sess_set_cache_size(ctx, NUM2LONG(arg));

    return arg;
}
session_cache_stats → Hash click to toggle source

Returns a Hash containing the following keys:

:accept

Number of started SSL/TLS handshakes in server mode

:accept_good

Number of established SSL/TLS sessions in server mode

:accept_renegotiate

Number of start renegotiations in server mode

:cache_full

Number of sessions that were removed due to cache overflow

:cache_hits

Number of successfully reused connections

:cache_misses

Number of sessions proposed by clients that were not found in the cache

:cache_num

Number of sessions in the internal session cache

:cb_hits

Number of sessions retrieved from the external cache in server mode

:connect

Number of started SSL/TLS handshakes in client mode

:connect_good

Number of established SSL/TLS sessions in client mode

:connect_renegotiate

Number of start renegotiations in client mode

:timeouts

Number of sessions proposed by clients that were found in the cache but had expired due to timeouts

static VALUE
ossl_sslctx_get_session_cache_stats(VALUE self)
{
    SSL_CTX *ctx;
    VALUE hash;

    Data_Get_Struct(self, SSL_CTX, ctx);

    hash = rb_hash_new();
    rb_hash_aset(hash, ID2SYM(rb_intern("cache_num")), LONG2NUM(SSL_CTX_sess_number(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("connect")), LONG2NUM(SSL_CTX_sess_connect(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("connect_good")), LONG2NUM(SSL_CTX_sess_connect_good(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("connect_renegotiate")), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("accept")), LONG2NUM(SSL_CTX_sess_accept(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("accept_good")), LONG2NUM(SSL_CTX_sess_accept_good(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("accept_renegotiate")), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("cache_hits")), LONG2NUM(SSL_CTX_sess_hits(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("cb_hits")), LONG2NUM(SSL_CTX_sess_cb_hits(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("cache_misses")), LONG2NUM(SSL_CTX_sess_misses(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("cache_full")), LONG2NUM(SSL_CTX_sess_cache_full(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("timeouts")), LONG2NUM(SSL_CTX_sess_timeouts(ctx)));

    return hash;
}
session_remove(session) → true | false click to toggle source

Removes session from the session cache

static VALUE
ossl_sslctx_session_remove(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    SSL_SESSION *sess;

    Data_Get_Struct(self, SSL_CTX, ctx);
    SafeGetSSLSession(arg, sess);

    return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse;
}
set_params(params={}) click to toggle source

Sets the parameters for this SSL context to the values in params. The keys in params must be assignment methods on SSLContext.

If the #verify_mode is not VERIFY_NONE and #ca_file, #ca_path and #cert_store are not set then the system default certificate store is used.

# File ext/openssl/lib/openssl/ssl.rb, line 46
def set_params(params={})
  params = DEFAULT_PARAMS.merge(params)
  params.each{|name, value| self.__send__("#{name}=", value) }
  if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
    unless self.ca_file or self.ca_path or self.cert_store
      self.cert_store = DEFAULT_CERT_STORE
    end
  end
  return params
end
setup → Qtrue # first time click to toggle source
setup → nil # thereafter

This method is called automatically when a new SSLSocket is created. Normally you do not need to call this method (unless you are writing an extension in C).

static VALUE
ossl_sslctx_setup(VALUE self)
{
    SSL_CTX *ctx;
    X509 *cert = NULL, *client_ca = NULL;
    X509_STORE *store;
    EVP_PKEY *key = NULL;
    char *ca_path = NULL, *ca_file = NULL;
    int i, verify_mode;
    VALUE val;

    if(OBJ_FROZEN(self)) return Qnil;
    Data_Get_Struct(self, SSL_CTX, ctx);

#if !defined(OPENSSL_NO_DH)
    if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){
        SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
    }
    else{
        SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback);
    }
#endif
    SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self);

    val = ossl_sslctx_get_cert_store(self);
    if(!NIL_P(val)){
        /*
         * WORKAROUND:
         *   X509_STORE can count references, but
         *   X509_STORE_free() doesn't care it.
         *   So we won't increment it but mark it by ex_data.
         */
        store = GetX509StorePtr(val); /* NO NEED TO DUP */
        SSL_CTX_set_cert_store(ctx, store);
        SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1);
    }

    val = ossl_sslctx_get_extra_cert(self);
    if(!NIL_P(val)){
        rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
    }

    /* private key may be bundled in certificate file. */
    val = ossl_sslctx_get_cert(self);
    cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
    val = ossl_sslctx_get_key(self);
    key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */
    if (cert && key) {
        if (!SSL_CTX_use_certificate(ctx, cert)) {
            /* Adds a ref => Safe to FREE */
            ossl_raise(eSSLError, "SSL_CTX_use_certificate");
        }
        if (!SSL_CTX_use_PrivateKey(ctx, key)) {
            /* Adds a ref => Safe to FREE */
            ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
        }
        if (!SSL_CTX_check_private_key(ctx)) {
            ossl_raise(eSSLError, "SSL_CTX_check_private_key");
        }
    }

    val = ossl_sslctx_get_client_ca(self);
    if(!NIL_P(val)){
        if(TYPE(val) == T_ARRAY){
            for(i = 0; i < RARRAY_LEN(val); i++){
                client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]);
                if (!SSL_CTX_add_client_CA(ctx, client_ca)){
                    /* Copies X509_NAME => FREE it. */
                    ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
                }
            }
        }
        else{
            client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
            if (!SSL_CTX_add_client_CA(ctx, client_ca)){
                /* Copies X509_NAME => FREE it. */
                ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
            }
        }
    }

    val = ossl_sslctx_get_ca_file(self);
    ca_file = NIL_P(val) ? NULL : StringValuePtr(val);
    val = ossl_sslctx_get_ca_path(self);
    ca_path = NIL_P(val) ? NULL : StringValuePtr(val);
    if(ca_file || ca_path){
        if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
            rb_warning("can't set verify locations");
    }

    val = ossl_sslctx_get_verify_mode(self);
    verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
    SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
    if (RTEST(ossl_sslctx_get_client_cert_cb(self)))
        SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);

    val = ossl_sslctx_get_timeout(self);
    if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));

    val = ossl_sslctx_get_verify_dep(self);
    if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));

    val = ossl_sslctx_get_options(self);
    if(!NIL_P(val)) {
        SSL_CTX_set_options(ctx, NUM2LONG(val));
    } else {
        SSL_CTX_set_options(ctx, SSL_OP_ALL);
    }

#ifdef HAVE_OPENSSL_NPN_NEGOTIATED
    val = rb_iv_get(self, "@npn_protocols");
    if (!NIL_P(val)) {
        ssl_npn_encode_protocols(self, val);
        SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *) self);
        OSSL_Debug("SSL NPN advertise callback added");
    }
    if (RTEST(rb_iv_get(self, "@npn_select_cb"))) {
        SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
        OSSL_Debug("SSL NPN select callback added");
    }
#endif

    rb_obj_freeze(self);

    val = ossl_sslctx_get_sess_id_ctx(self);
    if (!NIL_P(val)){
        StringValue(val);
        if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
                                            RSTRING_LENINT(val))){
            ossl_raise(eSSLError, "SSL_CTX_set_session_id_context");
        }
    }

    if (RTEST(rb_iv_get(self, "@session_get_cb"))) {
        SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
        OSSL_Debug("SSL SESSION get callback added");
    }
    if (RTEST(rb_iv_get(self, "@session_new_cb"))) {
        SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
        OSSL_Debug("SSL SESSION new callback added");
    }
    if (RTEST(rb_iv_get(self, "@session_remove_cb"))) {
        SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
        OSSL_Debug("SSL SESSION remove callback added");
    }

#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
    val = rb_iv_get(self, "@servername_cb");
    if (!NIL_P(val)) {
        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
        OSSL_Debug("SSL TLSEXT servername callback added");
    }
#endif

    return Qtrue;
}
ssl_version = :TLSv1 click to toggle source
ssl_version = "SSLv23_client"

You can get a list of valid versions with OpenSSL::SSL::SSLContext::METHODS

static VALUE
ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
{
    SSL_METHOD *method = NULL;
    const char *s;
    int i;

    SSL_CTX *ctx;
    if(TYPE(ssl_method) == T_SYMBOL)
        s = rb_id2name(SYM2ID(ssl_method));
    else
        s =  StringValuePtr(ssl_method);
    for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
        if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) {
            method = ossl_ssl_method_tab[i].func();
            break;
        }
    }
    if (!method) {
        ossl_raise(rb_eArgError, "unknown SSL method `%s'.", s);
    }
    Data_Get_Struct(self, SSL_CTX, ctx);
    if (SSL_CTX_set_ssl_version(ctx, method) != 1) {
        ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");
    }

    return ssl_method;
}


class OpenSSL::SSL::SSLError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::SSL::SSLError

Generic error class raised by SSLSocket and SSLContext.

In Files

  • ext/openssl/ossl_ssl.c

Parent

eOSSLError


class OpenSSL::SSL::SSLServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::SSL::SSLServer

In Files

  • ext/openssl/lib/openssl/ssl.rb

Parent

Object

Included Modules

  • OpenSSL::SSL::SocketForwarder

Attributes

start_immediately[RW]

Public Class Methods

new(svr, ctx) click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 155
def initialize(svr, ctx)
  @svr = svr
  @ctx = ctx
  unless ctx.session_id_context
    # see #6137 - session id may not exceed 32 bytes
    prng = ::Random.new($0.hash)
    session_id = prng.bytes(16).unpack('H*')[0]
    @ctx.session_id_context = session_id
  end
  @start_immediately = true
end

Public Instance Methods

accept() click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 179
def accept
  # Socket#accept returns [socket, addrinfo].
  # TCPServer#accept returns a socket.
  # The following comma strips addrinfo.
  sock, = @svr.accept
  begin
    ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
    ssl.sync_close = true
    ssl.accept if @start_immediately
    ssl
  rescue SSLError => ex
    sock.close
    raise ex
  end
end
close() click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 195
def close
  @svr.close
end
listen(backlog=5) click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 171
def listen(backlog=5)
  @svr.listen(backlog)
end
shutdown(how=Socket::SHUT_RDWR) click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 175
def shutdown(how=Socket::SHUT_RDWR)
  @svr.shutdown(how)
end
to_io() click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 167
def to_io
  @svr
end


class OpenSSL::SSL::SSLSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::SSL::SSLSocket

The following attributes are available but don't show up in rdoc.

  • io, context, sync_close

In Files

  • ext/openssl/lib/openssl/ssl.rb
  • ext/openssl/ossl_ssl.c

Parent

Object

Included Modules

  • OpenSSL::Buffering
  • OpenSSL::SSL::SocketForwarder
  • OpenSSL::SSL::Nonblock

Public Class Methods

new(io) → aSSLSocket click to toggle source
new(io, ctx) → aSSLSocket

Creates a new SSL socket from io which must be a real ruby object (not an IO-like object that responds to read/write.

If ctx is provided the SSL Sockets initial params will be taken from the context.

The OpenSSL::Buffering module provides additional IO methods.

This method will freeze the SSLContext if one is provided; however, session management is still allowed in the frozen SSLContext.

static VALUE
ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE io, ctx;

    if (rb_scan_args(argc, argv, "11", &io, &ctx) == 1) {
        ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
    }
    OSSL_Check_Kind(ctx, cSSLContext);
    Check_Type(io, T_FILE);
    ossl_ssl_set_io(self, io);
    ossl_ssl_set_ctx(self, ctx);
    ossl_ssl_set_sync_close(self, Qfalse);
    ossl_sslctx_setup(ctx);

    rb_iv_set(self, "@hostname", Qnil);

    rb_call_super(0, 0);

    return self;
}

Public Instance Methods

accept → self click to toggle source

Waits for a SSL/TLS client to initiate a handshake. The handshake may be started after unencrypted data has been sent over the socket.

static VALUE
ossl_ssl_accept(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0);
}
accept_nonblock → self click to toggle source

Initiates the SSL/TLS handshake as a server in non-blocking manner.

# emulates blocking accept
begin
  ssl.accept_nonblock
rescue IO::WaitReadable
  IO.select([s2])
  retry
rescue IO::WaitWritable
  IO.select(nil, [s2])
  retry
end
static VALUE
ossl_ssl_accept_nonblock(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1);
}
cert → cert or nil click to toggle source

The X509 certificate for this socket endpoint.

static VALUE
ossl_ssl_get_cert(VALUE self)
{
    SSL *ssl;
    X509 *cert = NULL;

    ossl_ssl_data_get_struct(self, ssl);

    /*
     * Is this OpenSSL bug? Should add a ref?
     * TODO: Ask for.
     */
    cert = SSL_get_certificate(ssl); /* NO DUPs => DON'T FREE. */

    if (!cert) {
        return Qnil;
    }
    return ossl_x509_new(cert);
}
cipher → [name, version, bits, alg_bits] click to toggle source

The cipher being used for the current connection

static VALUE
ossl_ssl_get_cipher(VALUE self)
{
    SSL *ssl;
    SSL_CIPHER *cipher;

    ossl_ssl_data_get_struct(self, ssl);

    cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl);

    return ossl_ssl_cipher_to_ary(cipher);
}
client_ca → [x509name, ...] click to toggle source

Returns the list of client CAs. Please note that in contrast to OpenSSL::SSL::SSLContext#client_ca no array of X509::Certificate is returned but X509::Name instances of the CA's subject distinguished name.

In server mode, returns the list set by OpenSSL::SSL::SSLContext#client_ca. In client mode, returns the list of client CAs sent from the server.

static VALUE
ossl_ssl_get_client_ca_list(VALUE self)
{
    SSL *ssl;
    STACK_OF(X509_NAME) *ca;

    ossl_ssl_data_get_struct(self, ssl);

    ca = SSL_get_client_CA_list(ssl);
    return ossl_x509name_sk2ary(ca);
}
connect → self click to toggle source

Initiates an SSL/TLS handshake with a server. The handshake may be started after unencrypted data has been sent over the socket.

static VALUE
ossl_ssl_connect(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0);
}
connect_nonblock → self click to toggle source

Initiates the SSL/TLS handshake as a client in non-blocking manner.

# emulates blocking connect
begin
  ssl.connect_nonblock
rescue IO::WaitReadable
  IO.select([s2])
  retry
rescue IO::WaitWritable
  IO.select(nil, [s2])
  retry
end
static VALUE
ossl_ssl_connect_nonblock(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1);
}
npn_protocol → String click to toggle source

Returns the protocol string that was finally selected by the client during the handshake.

static VALUE
ossl_ssl_npn_protocol(VALUE self)
{
    SSL *ssl;
    const unsigned char *out;
    unsigned int outlen;

    ossl_ssl_data_get_struct(self, ssl);

    SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
    if (!outlen)
        return Qnil;
    else
        return rb_str_new((const char *) out, outlen);
}
peer_cert → cert or nil click to toggle source

The X509 certificate for this socket's peer.

static VALUE
ossl_ssl_get_peer_cert(VALUE self)
{
    SSL *ssl;
    X509 *cert = NULL;
    VALUE obj;

    ossl_ssl_data_get_struct(self, ssl);

    cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */

    if (!cert) {
        return Qnil;
    }
    obj = ossl_x509_new(cert);
    X509_free(cert);

    return obj;
}
peer_cert_chain → [cert, ...] or nil click to toggle source

The X509 certificate chain for this socket's peer.

static VALUE
ossl_ssl_get_peer_cert_chain(VALUE self)
{
    SSL *ssl;
    STACK_OF(X509) *chain;
    X509 *cert;
    VALUE ary;
    int i, num;

    ossl_ssl_data_get_struct(self, ssl);

    chain = SSL_get_peer_cert_chain(ssl);
    if(!chain) return Qnil;
    num = sk_X509_num(chain);
    ary = rb_ary_new2(num);
    for (i = 0; i < num; i++){
        cert = sk_X509_value(chain, i);
        rb_ary_push(ary, ossl_x509_new(cert));
    }

    return ary;
}
pending → Integer click to toggle source

The number of bytes that are immediately available for reading

static VALUE
ossl_ssl_pending(VALUE self)
{
    SSL *ssl;

    ossl_ssl_data_get_struct(self, ssl);

    return INT2NUM(SSL_pending(ssl));
}
post_connection_check(hostname) click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 137
def post_connection_check(hostname)
  unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
    raise SSLError, "hostname \"#{hostname}\" does not match the server certificate"
  end
  return true
end
session() click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 144
def session
  SSL::Session.new(self)
rescue SSL::Session::SessionError
  nil
end
session = session → session click to toggle source

Sets the Session to be used when the connection is established.

static VALUE
ossl_ssl_set_session(VALUE self, VALUE arg1)
{
    SSL *ssl;
    SSL_SESSION *sess;

/* why is ossl_ssl_setup delayed? */
    ossl_ssl_setup(self);

    ossl_ssl_data_get_struct(self, ssl);

    SafeGetSSLSession(arg1, sess);

    if (SSL_set_session(ssl, sess) != 1)
        ossl_raise(eSSLError, "SSL_set_session");

    return arg1;
}
session_reused? → true | false click to toggle source

Returns true if a reused session was negotiated during the handshake.

static VALUE
ossl_ssl_session_reused(VALUE self)
{
    SSL *ssl;

    ossl_ssl_data_get_struct(self, ssl);

    switch(SSL_session_reused(ssl)) {
    case 1:     return Qtrue;
    case 0:     return Qfalse;
    default:    ossl_raise(eSSLError, "SSL_session_reused");
    }

    UNREACHABLE;
}
version → String click to toggle source

Returns a String representing the SSL/TLS version that was negotiated for the connection, for example “TLSv1.2”.

static VALUE
ossl_ssl_get_version(VALUE self)
{
    SSL *ssl;

    ossl_ssl_data_get_struct(self, ssl);

    return rb_str_new2(SSL_get_version(ssl));
}
state → string click to toggle source

A description of the current connection state.

static VALUE
ossl_ssl_get_state(VALUE self)
{
    SSL *ssl;
    VALUE ret;

    ossl_ssl_data_get_struct(self, ssl);

    ret = rb_str_new2(SSL_state_string(ssl));
    if (ruby_verbose) {
        rb_str_cat2(ret, ": ");
        rb_str_cat2(ret, SSL_state_string_long(ssl));
    }
    return ret;
}
sysclose → nil click to toggle source

Shuts down the SSL connection and prepares it for another connection.

static VALUE
ossl_ssl_close(VALUE self)
{
    SSL *ssl;

    ossl_ssl_data_get_struct(self, ssl);

    if (ssl) {
        VALUE io = ossl_ssl_get_io(self);
        if (!RTEST(rb_funcall(io, rb_intern("closed?"), 0))) {
            ossl_ssl_shutdown(ssl);
            SSL_free(ssl);
            DATA_PTR(self) = NULL;
            if (RTEST(ossl_ssl_get_sync_close(self)))
                rb_funcall(io, rb_intern("close"), 0);
        }
    }

    return Qnil;
}
sysread(length) → string click to toggle source
sysread(length, buffer) → buffer

Reads length bytes from the SSL connection. If a pre-allocated buffer is provided the data will be written into it.

static VALUE
ossl_ssl_read(int argc, VALUE *argv, VALUE self)
{
    return ossl_ssl_read_internal(argc, argv, self, 0);
}
syswrite(string) → Integer click to toggle source

Writes string to the SSL connection.

static VALUE
ossl_ssl_write(VALUE self, VALUE str)
{
    return ossl_ssl_write_internal(self, str, 0);
}
verify_result → Integer click to toggle source

Returns the result of the peer certificates verification. See verify(1) for error values and descriptions.

If no peer certificate was presented X509_V_OK is returned.

static VALUE
ossl_ssl_get_verify_result(VALUE self)
{
    SSL *ssl;

    ossl_ssl_data_get_struct(self, ssl);

    return INT2FIX(SSL_get_verify_result(ssl));
}


class OpenSSL::SSL::Session - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::SSL::Session

let rdoc know about mOSSL

In Files

  • ext/openssl/ossl_ssl.c

Parent

Object

Public Class Methods

new(SSLSocket | string) → session click to toggle source

Parameters

SSLSocket is an OpenSSL::SSL::SSLSocket string must be a DER or PEM encoded Session.

static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1)
{
        SSL_SESSION *ctx = NULL;

        if (RDATA(self)->data)
                ossl_raise(eSSLSession, "SSL Session already initialized");

        if (rb_obj_is_instance_of(arg1, cSSLSocket)) {
                SSL *ssl;

                Data_Get_Struct(arg1, SSL, ssl);

                if (!ssl || (ctx = SSL_get1_session(ssl)) == NULL)
                        ossl_raise(eSSLSession, "no session available");
        } else {
                BIO *in = ossl_obj2bio(arg1);

                ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);

                if (!ctx) {
                        OSSL_BIO_reset(in);
                        ctx = d2i_SSL_SESSION_bio(in, NULL);
                }

                BIO_free(in);

                if (!ctx)
                        ossl_raise(rb_eArgError, "unknown type");
        }

        /* should not happen */
        if (ctx == NULL)
                ossl_raise(eSSLSession, "ctx not set - internal error");

        RDATA(self)->data = ctx;

        return self;
}

Public Instance Methods

session1 == session2 → boolean click to toggle source
static VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2)
{
        SSL_SESSION *ctx1, *ctx2;

        GetSSLSession(val1, ctx1);
        SafeGetSSLSession(val2, ctx2);

        switch (SSL_SESSION_cmp(ctx1, ctx2)) {
        case 0:                return Qtrue;
        default:       return Qfalse;
        }
}
id → aString click to toggle source

Returns the Session ID.

static VALUE ossl_ssl_session_get_id(VALUE self)
{
        SSL_SESSION *ctx;
        const unsigned char *p = NULL;
        unsigned int i = 0;

        GetSSLSession(self, ctx);

        p = SSL_SESSION_get_id(ctx, &i);

        return rb_str_new((const char *) p, i);
}
time → Time click to toggle source

Gets start time of the session.

static VALUE ossl_ssl_session_get_time(VALUE self)
{
        SSL_SESSION *ctx;
        time_t t;

        GetSSLSession(self, ctx);

        t = SSL_SESSION_get_time(ctx);

        if (t == 0)
                return Qnil;

        return rb_funcall(rb_cTime, rb_intern("at"), 1, TIMET2NUM(t));
}
time=(Time) → Time click to toggle source
time=(integer) → Time

Sets start time of the session. Time resolution is in seconds.

static VALUE ossl_ssl_session_set_time(VALUE self, VALUE time_v)
{
        SSL_SESSION *ctx;
        long t;

        GetSSLSession(self, ctx);
        if (rb_obj_is_instance_of(time_v, rb_cTime)) {
                time_v = rb_funcall(time_v, rb_intern("to_i"), 0);
        }
        t = NUM2LONG(time_v);
        SSL_SESSION_set_time(ctx, t);
        return ossl_ssl_session_get_time(self);
}
timeout → integer click to toggle source

Gets how long until the session expires in seconds.

static VALUE ossl_ssl_session_get_timeout(VALUE self)
{
        SSL_SESSION *ctx;
        time_t t;

        GetSSLSession(self, ctx);

        t = SSL_SESSION_get_timeout(ctx);

        return TIMET2NUM(t);
}
timeout=(integer) → integer click to toggle source

Sets how long until the session expires in seconds.

static VALUE ossl_ssl_session_set_timeout(VALUE self, VALUE time_v)
{
        SSL_SESSION *ctx;
        long t;

        GetSSLSession(self, ctx);
        t = NUM2LONG(time_v);
        SSL_SESSION_set_timeout(ctx, t);
        return ossl_ssl_session_get_timeout(self);
}
to_der → aString click to toggle source

Returns an ASN1 encoded String that contains the Session object.

static VALUE ossl_ssl_session_to_der(VALUE self)
{
        SSL_SESSION *ctx;
        unsigned char *p;
        int len;
        VALUE str;

        GetSSLSession(self, ctx);
        len = i2d_SSL_SESSION(ctx, NULL);
        if (len <= 0) {
                ossl_raise(eSSLSession, "i2d_SSL_SESSION");
        }

        str = rb_str_new(0, len);
        p = (unsigned char *)RSTRING_PTR(str);
        i2d_SSL_SESSION(ctx, &p);
        ossl_str_adjust(str, p);
        return str;
}
to_pem → String click to toggle source

Returns a PEM encoded String that contains the Session object.

static VALUE ossl_ssl_session_to_pem(VALUE self)
{
        SSL_SESSION *ctx;
        BIO *out;
        BUF_MEM *buf;
        VALUE str;
        int i;

        GetSSLSession(self, ctx);

        if (!(out = BIO_new(BIO_s_mem()))) {
                ossl_raise(eSSLSession, "BIO_s_mem()");
        }

        if (!(i=PEM_write_bio_SSL_SESSION(out, ctx))) {
                BIO_free(out);
                ossl_raise(eSSLSession, "SSL_SESSION_print()");
        }

        BIO_get_mem_ptr(out, &buf);
        str = rb_str_new(buf->data, buf->length);
        BIO_free(out);

        return str;
}
to_text → String click to toggle source

Shows everything in the Session object.

static VALUE ossl_ssl_session_to_text(VALUE self)
{
        SSL_SESSION *ctx;
        BIO *out;
        BUF_MEM *buf;
        VALUE str;

        GetSSLSession(self, ctx);

        if (!(out = BIO_new(BIO_s_mem()))) {
                ossl_raise(eSSLSession, "BIO_s_mem()");
        }

        if (!SSL_SESSION_print(out, ctx)) {
                BIO_free(out);
                ossl_raise(eSSLSession, "SSL_SESSION_print()");
        }

        BIO_get_mem_ptr(out, &buf);
        str = rb_str_new(buf->data, buf->length);
        BIO_free(out);

        return str;
}


class OpenSSL::SSL::Session::SessionError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::SSL::Session::SessionError

let rdoc know about mOSSL

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

eOSSLError


module OpenSSL::SSL::SocketForwarder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::SSL::SocketForwarder

In Files

  • ext/openssl/lib/openssl/ssl.rb

Public Instance Methods

addr() click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 59
def addr
  to_io.addr
end
closed?() click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 79
def closed?
  to_io.closed?
end
do_not_reverse_lookup=(flag) click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 83
def do_not_reverse_lookup=(flag)
  to_io.do_not_reverse_lookup = flag
end
fcntl(*args) click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 75
def fcntl(*args)
  to_io.fcntl(*args)
end
getsockopt(level, optname) click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 71
def getsockopt(level, optname)
  to_io.getsockopt(level, optname)
end
peeraddr() click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 63
def peeraddr
  to_io.peeraddr
end
setsockopt(level, optname, optval) click to toggle source
# File ext/openssl/lib/openssl/ssl.rb, line 67
def setsockopt(level, optname, optval)
  to_io.setsockopt(level, optname, optval)
end


module OpenSSL::X509 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::X509

let rdoc know about mOSSL

let rdoc know about mOSSL

In Files

  • ext/openssl/lib/openssl/x509.rb
  • ext/openssl/ossl.c


class OpenSSL::X509::Attribute - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::Attribute

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

Object

Public Class Methods

new(oid [, value]) → attr click to toggle source
static VALUE
ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE oid, value;
    X509_ATTRIBUTE *attr, *x;
    const unsigned char *p;

    GetX509Attr(self, attr);
    if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){
        oid = ossl_to_der_if_possible(oid);
        StringValue(oid);
        p = (unsigned char *)RSTRING_PTR(oid);
        x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid));
        DATA_PTR(self) = attr;
        if(!x){
            ossl_raise(eX509AttrError, NULL);
        }
        return self;
    }
    rb_funcall(self, rb_intern("oid="), 1, oid);
    rb_funcall(self, rb_intern("value="), 1, value);

    return self;
}

Public Instance Methods

oid → string click to toggle source
static VALUE
ossl_x509attr_get_oid(VALUE self)
{
    X509_ATTRIBUTE *attr;
    ASN1_OBJECT *oid;
    BIO *out;
    VALUE ret;
    int nid;

    GetX509Attr(self, attr);
    oid = X509_ATTRIBUTE_get0_object(attr);
    if ((nid = OBJ_obj2nid(oid)) != NID_undef)
        ret = rb_str_new2(OBJ_nid2sn(nid));
    else{
        if (!(out = BIO_new(BIO_s_mem())))
            ossl_raise(eX509AttrError, NULL);
        i2a_ASN1_OBJECT(out, oid);
        ret = ossl_membio2str(out);
    }

    return ret;
}
oid = string → string click to toggle source
static VALUE
ossl_x509attr_set_oid(VALUE self, VALUE oid)
{
    X509_ATTRIBUTE *attr;
    ASN1_OBJECT *obj;
    char *s;

    s = StringValuePtr(oid);
    obj = OBJ_txt2obj(s, 0);
    if(!obj) obj = OBJ_txt2obj(s, 1);
    if(!obj) ossl_raise(eX509AttrError, NULL);
    GetX509Attr(self, attr);
    X509_ATTRIBUTE_set1_object(attr, obj);

    return oid;
}
to_der → string click to toggle source
static VALUE
ossl_x509attr_to_der(VALUE self)
{
    X509_ATTRIBUTE *attr;
    VALUE str;
    int len;
    unsigned char *p;

    GetX509Attr(self, attr);
    if((len = i2d_X509_ATTRIBUTE(attr, NULL)) <= 0)
        ossl_raise(eX509AttrError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_X509_ATTRIBUTE(attr, &p) <= 0)
        ossl_raise(eX509AttrError, NULL);
    rb_str_set_len(str, p - (unsigned char*)RSTRING_PTR(str));

    return str;
}
value → asn1 click to toggle source
static VALUE
ossl_x509attr_get_value(VALUE self)
{
    X509_ATTRIBUTE *attr;
    VALUE str, asn1;
    long length;
    unsigned char *p;

    GetX509Attr(self, attr);
    if(attr->value.ptr == NULL) return Qnil;
    if(OSSL_X509ATTR_IS_SINGLE(attr)){
        length = i2d_ASN1_TYPE(attr->value.single, NULL);
        str = rb_str_new(0, length);
        p = (unsigned char *)RSTRING_PTR(str);
        i2d_ASN1_TYPE(attr->value.single, &p);
        ossl_str_adjust(str, p);
    }
    else{
        length = i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set,
                        (unsigned char **) NULL, i2d_ASN1_TYPE,
                        V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
        str = rb_str_new(0, length);
        p = (unsigned char *)RSTRING_PTR(str);
        i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, &p,
                        i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
        ossl_str_adjust(str, p);
    }
    asn1 = rb_funcall(mASN1, rb_intern("decode"), 1, str);

    return asn1;
}
value = asn1 → asn1 click to toggle source
static VALUE
ossl_x509attr_set_value(VALUE self, VALUE value)
{
    X509_ATTRIBUTE *attr;
    ASN1_TYPE *a1type;

    if(!(a1type = ossl_asn1_get_asn1type(value)))
        ossl_raise(eASN1Error, "could not get ASN1_TYPE");
    if(ASN1_TYPE_get(a1type) == V_ASN1_SEQUENCE){
        ASN1_TYPE_free(a1type);
        ossl_raise(eASN1Error, "couldn't set SEQUENCE for attribute value.");
    }
    GetX509Attr(self, attr);
    if(attr->value.set){
        if(OSSL_X509ATTR_IS_SINGLE(attr)) ASN1_TYPE_free(attr->value.single);
        else sk_ASN1_TYPE_free(attr->value.set);
    }
    OSSL_X509ATTR_SET_SINGLE(attr);
    attr->value.single = a1type;

    return value;
}


class OpenSSL::X509::AttributeError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::AttributeError

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

eOSSLError


class OpenSSL::X509::CRL - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::CRL

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

Object

Public Class Methods

new(p1 = v1) click to toggle source
static VALUE
ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self)
{
    BIO *in;
    X509_CRL *crl, *x = DATA_PTR(self);
    VALUE arg;

    if (rb_scan_args(argc, argv, "01", &arg) == 0) {
        return self;
    }
    arg = ossl_to_der_if_possible(arg);
    in = ossl_obj2bio(arg);
    crl = PEM_read_bio_X509_CRL(in, &x, NULL, NULL);
    DATA_PTR(self) = x;
    if (!crl) {
        OSSL_BIO_reset(in);
        crl = d2i_X509_CRL_bio(in, &x);
        DATA_PTR(self) = x;
    }
    BIO_free(in);
    if (!crl) ossl_raise(eX509CRLError, NULL);

    return self;
}

Public Instance Methods

add_extension(p1) click to toggle source
static VALUE
ossl_x509crl_add_extension(VALUE self, VALUE extension)
{
    X509_CRL *crl;
    X509_EXTENSION *ext;

    GetX509CRL(self, crl);
    ext = DupX509ExtPtr(extension);
    if (!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */
        X509_EXTENSION_free(ext);
        ossl_raise(eX509CRLError, NULL);
    }
    X509_EXTENSION_free(ext);

    return extension;
}
add_revoked(p1) click to toggle source
static VALUE
ossl_x509crl_add_revoked(VALUE self, VALUE revoked)
{
    X509_CRL *crl;
    X509_REVOKED *rev;

    GetX509CRL(self, crl);
    rev = DupX509RevokedPtr(revoked);
    if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */
        ossl_raise(eX509CRLError, NULL);
    }
    X509_CRL_sort(crl);

    return revoked;
}
extensions() click to toggle source

Gets X509v3 extensions as array of X509Ext objects

static VALUE
ossl_x509crl_get_extensions(VALUE self)
{
    X509_CRL *crl;
    int count, i;
    X509_EXTENSION *ext;
    VALUE ary;

    GetX509CRL(self, crl);
    count = X509_CRL_get_ext_count(crl);
    if (count < 0) {
        OSSL_Debug("count < 0???");
        return rb_ary_new();
    }
    ary = rb_ary_new2(count);
    for (i=0; i<count; i++) {
        ext = X509_CRL_get_ext(crl, i); /* NO DUP - don't free! */
        rb_ary_push(ary, ossl_x509ext_new(ext));
    }

    return ary;
}
extensions=(p1) click to toggle source

Sets X509_EXTENSIONs

static VALUE
ossl_x509crl_set_extensions(VALUE self, VALUE ary)
{
    X509_CRL *crl;
    X509_EXTENSION *ext;
    int i;

    Check_Type(ary, T_ARRAY);
    /* All ary members should be X509 Extensions */
    for (i=0; i<RARRAY_LEN(ary); i++) {
        OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext);
    }
    GetX509CRL(self, crl);
    sk_X509_EXTENSION_pop_free(crl->crl->extensions, X509_EXTENSION_free);
    crl->crl->extensions = NULL;
    for (i=0; i<RARRAY_LEN(ary); i++) {
        ext = DupX509ExtPtr(RARRAY_PTR(ary)[i]);
        if(!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */
            X509_EXTENSION_free(ext);
            ossl_raise(eX509CRLError, NULL);
        }
        X509_EXTENSION_free(ext);
    }

    return ary;
}
issuer() click to toggle source
static VALUE
ossl_x509crl_get_issuer(VALUE self)
{
    X509_CRL *crl;

    GetX509CRL(self, crl);

    return ossl_x509name_new(X509_CRL_get_issuer(crl)); /* NO DUP - don't free */
}
issuer=(p1) click to toggle source
static VALUE
ossl_x509crl_set_issuer(VALUE self, VALUE issuer)
{
    X509_CRL *crl;

    GetX509CRL(self, crl);

    if (!X509_CRL_set_issuer_name(crl, GetX509NamePtr(issuer))) { /* DUPs name */
        ossl_raise(eX509CRLError, NULL);
    }
    return issuer;
}
last_update() click to toggle source
static VALUE
ossl_x509crl_get_last_update(VALUE self)
{
    X509_CRL *crl;

    GetX509CRL(self, crl);

    return asn1time_to_time(X509_CRL_get_lastUpdate(crl));
}
last_update=(p1) click to toggle source
static VALUE
ossl_x509crl_set_last_update(VALUE self, VALUE time)
{
    X509_CRL *crl;
    time_t sec;

    sec = time_to_time_t(time);
    GetX509CRL(self, crl);
    if (!X509_time_adj(crl->crl->lastUpdate, 0, &sec)) {
        ossl_raise(eX509CRLError, NULL);
    }

    return time;
}
next_update() click to toggle source
static VALUE
ossl_x509crl_get_next_update(VALUE self)
{
    X509_CRL *crl;

    GetX509CRL(self, crl);

    return asn1time_to_time(X509_CRL_get_nextUpdate(crl));
}
next_update=(p1) click to toggle source
static VALUE
ossl_x509crl_set_next_update(VALUE self, VALUE time)
{
    X509_CRL *crl;
    time_t sec;

    sec = time_to_time_t(time);
    GetX509CRL(self, crl);
    /* This must be some thinko in OpenSSL */
    if (!(crl->crl->nextUpdate = X509_time_adj(crl->crl->nextUpdate, 0, &sec))){
        ossl_raise(eX509CRLError, NULL);
    }

    return time;
}
revoked() click to toggle source
static VALUE
ossl_x509crl_get_revoked(VALUE self)
{
    X509_CRL *crl;
    int i, num;
    X509_REVOKED *rev;
    VALUE ary, revoked;

    GetX509CRL(self, crl);
    num = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
    if (num < 0) {
        OSSL_Debug("num < 0???");
        return rb_ary_new();
    }
    ary = rb_ary_new2(num);
    for(i=0; i<num; i++) {
        /* NO DUP - don't free! */
        rev = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
        revoked = ossl_x509revoked_new(rev);
        rb_ary_push(ary, revoked);
    }

    return ary;
}
revoked=(p1) click to toggle source
static VALUE
ossl_x509crl_set_revoked(VALUE self, VALUE ary)
{
    X509_CRL *crl;
    X509_REVOKED *rev;
    int i;

    Check_Type(ary, T_ARRAY);
    /* All ary members should be X509 Revoked */
    for (i=0; i<RARRAY_LEN(ary); i++) {
        OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Rev);
    }
    GetX509CRL(self, crl);
    sk_X509_REVOKED_pop_free(crl->crl->revoked, X509_REVOKED_free);
    crl->crl->revoked = NULL;
    for (i=0; i<RARRAY_LEN(ary); i++) {
        rev = DupX509RevokedPtr(RARRAY_PTR(ary)[i]);
        if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */
            ossl_raise(eX509CRLError, NULL);
        }
    }
    X509_CRL_sort(crl);

    return ary;
}
sign(p1, p2) click to toggle source
static VALUE
ossl_x509crl_sign(VALUE self, VALUE key, VALUE digest)
{
    X509_CRL *crl;
    EVP_PKEY *pkey;
    const EVP_MD *md;

    GetX509CRL(self, crl);
    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
    md = GetDigestPtr(digest);
    if (!X509_CRL_sign(crl, pkey, md)) {
        ossl_raise(eX509CRLError, NULL);
    }

    return self;
}
signature_algorithm() click to toggle source
static VALUE
ossl_x509crl_get_signature_algorithm(VALUE self)
{
    X509_CRL *crl;
    BIO *out;
    BUF_MEM *buf;
    VALUE str;

    GetX509CRL(self, crl);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eX509CRLError, NULL);
    }
    if (!i2a_ASN1_OBJECT(out, crl->sig_alg->algorithm)) {
        BIO_free(out);
        ossl_raise(eX509CRLError, NULL);
    }
    BIO_get_mem_ptr(out, &buf);
    str = rb_str_new(buf->data, buf->length);
    BIO_free(out);
    return str;
}
to_der() click to toggle source
static VALUE
ossl_x509crl_to_der(VALUE self)
{
    X509_CRL *crl;
    BIO *out;
    BUF_MEM *buf;
    VALUE str;

    GetX509CRL(self, crl);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eX509CRLError, NULL);
    }
    if (!i2d_X509_CRL_bio(out, crl)) {
        BIO_free(out);
        ossl_raise(eX509CRLError, NULL);
    }
    BIO_get_mem_ptr(out, &buf);
    str = rb_str_new(buf->data, buf->length);
    BIO_free(out);

    return str;
}
to_pem() click to toggle source
static VALUE
ossl_x509crl_to_pem(VALUE self)
{
    X509_CRL *crl;
    BIO *out;
    BUF_MEM *buf;
    VALUE str;

    GetX509CRL(self, crl);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eX509CRLError, NULL);
    }
    if (!PEM_write_bio_X509_CRL(out, crl)) {
        BIO_free(out);
        ossl_raise(eX509CRLError, NULL);
    }
    BIO_get_mem_ptr(out, &buf);
    str = rb_str_new(buf->data, buf->length);
    BIO_free(out);

    return str;
}
Also aliased as: to_s
to_s() click to toggle source
Alias for: to_pem
to_text() click to toggle source
static VALUE
ossl_x509crl_to_text(VALUE self)
{
    X509_CRL *crl;
    BIO *out;
    BUF_MEM *buf;
    VALUE str;

    GetX509CRL(self, crl);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eX509CRLError, NULL);
    }
    if (!X509_CRL_print(out, crl)) {
        BIO_free(out);
        ossl_raise(eX509CRLError, NULL);
    }
    BIO_get_mem_ptr(out, &buf);
    str = rb_str_new(buf->data, buf->length);
    BIO_free(out);

    return str;
}
verify(p1) click to toggle source
static VALUE
ossl_x509crl_verify(VALUE self, VALUE key)
{
    X509_CRL *crl;
    int ret;

    GetX509CRL(self, crl);
    if ((ret = X509_CRL_verify(crl, GetPKeyPtr(key))) < 0) {
        ossl_raise(eX509CRLError, NULL);
    }
    if (ret == 1) {
        return Qtrue;
    }

    return Qfalse;
}
version() click to toggle source
static VALUE
ossl_x509crl_get_version(VALUE self)
{
    X509_CRL *crl;
    long ver;

    GetX509CRL(self, crl);
    ver = X509_CRL_get_version(crl);

    return LONG2NUM(ver);
}
version=(p1) click to toggle source
static VALUE
ossl_x509crl_set_version(VALUE self, VALUE version)
{
    X509_CRL *crl;
    long ver;

    if ((ver = NUM2LONG(version)) < 0) {
        ossl_raise(eX509CRLError, "version must be >= 0!");
    }
    GetX509CRL(self, crl);
    if (!X509_CRL_set_version(crl, ver)) {
        ossl_raise(eX509CRLError, NULL);
    }

    return version;
}


class OpenSSL::X509::CRLError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::CRLError

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

eOSSLError


class OpenSSL::X509::Certificate - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::Certificate

Implementation of an X.509 certificate as specified in RFC 5280. Provides access to a certificate's attributes and allows certificates to be read from a string, but also supports the creation of new certificates from scratch.

Reading a certificate from a file

Certificate is capable of handling DER-encoded certificates and certificates encoded in OpenSSL's PEM format.

raw = File.read "cert.cer" # DER- or PEM-encoded
certificate = OpenSSL::X509::Certificate.new raw

Saving a certificate to a file

A certificate may be encoded in DER format

cert = ...
File.open("cert.cer", "wb") { |f| f.print cert.to_der }

or in PEM format

cert = ...
File.open("cert.pem", "wb") { |f| f.print cert.to_pem }

X.509 certificates are associated with a private/public key pair, typically a RSA, DSA or ECC key (see also OpenSSL::PKey::RSA, OpenSSL::PKey::DSA and OpenSSL::PKey::EC), the public key itself is stored within the certificate and can be accessed in form of an OpenSSL::PKey. Certificates are typically used to be able to associate some form of identity with a key pair, for example web servers serving pages over HTTPs use certificates to authenticate themselves to the user.

The public key infrastructure (PKI) model relies on trusted certificate authorities (“root CAs”) that issue these certificates, so that end users need to base their trust just on a selected few authorities that themselves again vouch for subordinate CAs issuing their certificates to end users.

The OpenSSL::X509 module provides the tools to set up an independent PKI, similar to scenarios where the 'openssl' command line tool is used for issuing certificates in a private PKI.

Creating a root CA certificate and an end-entity certificate

First, we need to create a “self-signed” root certificate. To do so, we need to generate a key first. Please note that the choice of “1” as a serial number is considered a security flaw for real certificates. Secure choices are integers in the two-digit byte range and ideally not sequential but secure random numbers, steps omitted here to keep the example concise.

root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
root_ca = OpenSSL::X509::Certificate.new
root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
root_ca.serial = 1
root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA"
root_ca.issuer = root_ca.subject # root CA's are "self-signed"
root_ca.public_key = root_key.public_key
root_ca.not_before = Time.now
root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = root_ca
ef.issuer_certificate = root_ca
root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)

The next step is to create the end-entity certificate using the root CA certificate.

key = OpenSSL::PKey::RSA.new 2048
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = 2
cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate"
cert.issuer = root_ca.subject # root CA is the issuer
cert.public_key = key.public_key
cert.not_before = Time.now
cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity
ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = cert
ef.issuer_certificate = root_ca
cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
cert.sign(root_key, OpenSSL::Digest::SHA256.new)

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

Object

Public Class Methods

new → cert click to toggle source
new(string) → cert
static VALUE
ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
{
    BIO *in;
    X509 *x509, *x = DATA_PTR(self);
    VALUE arg;

    if (rb_scan_args(argc, argv, "01", &arg) == 0) {
        /* create just empty X509Cert */
        return self;
    }
    arg = ossl_to_der_if_possible(arg);
    in = ossl_obj2bio(arg);
    x509 = PEM_read_bio_X509(in, &x, NULL, NULL);
    DATA_PTR(self) = x;
    if (!x509) {
        OSSL_BIO_reset(in);
        x509 = d2i_X509_bio(in, &x);
        DATA_PTR(self) = x;
    }
    BIO_free(in);
    if (!x509) ossl_raise(eX509CertError, NULL);

    return self;
}

Public Instance Methods

add_extension(extension) → extension click to toggle source
static VALUE
ossl_x509_add_extension(VALUE self, VALUE extension)
{
    X509 *x509;
    X509_EXTENSION *ext;

    GetX509(self, x509);
    ext = DupX509ExtPtr(extension);
    if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */
        X509_EXTENSION_free(ext);
        ossl_raise(eX509CertError, NULL);
    }
    X509_EXTENSION_free(ext);

    return extension;
}
check_private_key(key) click to toggle source

Checks if 'key' is PRIV key for this cert

static VALUE
ossl_x509_check_private_key(VALUE self, VALUE key)
{
    X509 *x509;
    EVP_PKEY *pkey;

    /* not needed private key, but should be */
    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
    GetX509(self, x509);
    if (!X509_check_private_key(x509, pkey)) {
        OSSL_Warning("Check private key:%s", OSSL_ErrMsg());
        return Qfalse;
    }

    return Qtrue;
}
extensions → [extension...] click to toggle source
static VALUE
ossl_x509_get_extensions(VALUE self)
{
    X509 *x509;
    int count, i;
    X509_EXTENSION *ext;
    VALUE ary;

    GetX509(self, x509);
    count = X509_get_ext_count(x509);
    if (count < 0) {
        return rb_ary_new();
    }
    ary = rb_ary_new2(count);
    for (i=0; i<count; i++) {
        ext = X509_get_ext(x509, i); /* NO DUP - don't free! */
        rb_ary_push(ary, ossl_x509ext_new(ext));
    }

    return ary;
}
extensions = [ext...] → [ext...] click to toggle source
static VALUE
ossl_x509_set_extensions(VALUE self, VALUE ary)
{
    X509 *x509;
    X509_EXTENSION *ext;
    int i;

    Check_Type(ary, T_ARRAY);
    /* All ary's members should be X509Extension */
    for (i=0; i<RARRAY_LEN(ary); i++) {
        OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext);
    }
    GetX509(self, x509);
    sk_X509_EXTENSION_pop_free(x509->cert_info->extensions, X509_EXTENSION_free);
    x509->cert_info->extensions = NULL;
    for (i=0; i<RARRAY_LEN(ary); i++) {
        ext = DupX509ExtPtr(RARRAY_PTR(ary)[i]);

        if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */
            X509_EXTENSION_free(ext);
            ossl_raise(eX509CertError, NULL);
        }
        X509_EXTENSION_free(ext);
    }

    return ary;
}
inspect() click to toggle source
static VALUE
ossl_x509_inspect(VALUE self)
{
    return rb_sprintf("#<%"PRIsVALUE": subject=%+"PRIsVALUE", "
                      "issuer=%+"PRIsVALUE", serial=%+"PRIsVALUE", "
                      "not_before=%+"PRIsVALUE", not_after=%+"PRIsVALUE">",
                      rb_obj_class(self),
                      ossl_x509_get_subject(self),
                      ossl_x509_get_issuer(self),
                      ossl_x509_get_serial(self),
                      ossl_x509_get_not_before(self),
                      ossl_x509_get_not_after(self));
}
issuer → name click to toggle source
static VALUE
ossl_x509_get_issuer(VALUE self)
{
    X509 *x509;
    X509_NAME *name;

    GetX509(self, x509);
    if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */
        ossl_raise(eX509CertError, NULL);
    }

    return ossl_x509name_new(name);
}
issuer = name → name click to toggle source
static VALUE
ossl_x509_set_issuer(VALUE self, VALUE issuer)
{
    X509 *x509;

    GetX509(self, x509);
    if (!X509_set_issuer_name(x509, GetX509NamePtr(issuer))) { /* DUPs name */
        ossl_raise(eX509CertError, NULL);
    }

    return issuer;
}
not_after → time click to toggle source
static VALUE
ossl_x509_get_not_after(VALUE self)
{
    X509 *x509;
    ASN1_TIME *asn1time;

    GetX509(self, x509);
    if (!(asn1time = X509_get_notAfter(x509))) { /* NO DUP - don't free! */
        ossl_raise(eX509CertError, NULL);
    }

    return asn1time_to_time(asn1time);
}
not_after = time → time click to toggle source
static VALUE
ossl_x509_set_not_after(VALUE self, VALUE time)
{
    X509 *x509;
    time_t sec;

    sec = time_to_time_t(time);
    GetX509(self, x509);
    if (!X509_time_adj(X509_get_notAfter(x509), 0, &sec)) {
        ossl_raise(eX509CertError, NULL);
    }

    return time;
}
not_before → time click to toggle source
static VALUE
ossl_x509_get_not_before(VALUE self)
{
    X509 *x509;
    ASN1_UTCTIME *asn1time;

    GetX509(self, x509);
    if (!(asn1time = X509_get_notBefore(x509))) { /* NO DUP - don't free! */
        ossl_raise(eX509CertError, NULL);
    }

    return asn1time_to_time(asn1time);
}
not_before = time → time click to toggle source
static VALUE
ossl_x509_set_not_before(VALUE self, VALUE time)
{
    X509 *x509;
    time_t sec;

    sec = time_to_time_t(time);
    GetX509(self, x509);
    if (!X509_time_adj(X509_get_notBefore(x509), 0, &sec)) {
        ossl_raise(eX509CertError, NULL);
    }

    return time;
}
public_key → key click to toggle source
static VALUE
ossl_x509_get_public_key(VALUE self)
{
    X509 *x509;
    EVP_PKEY *pkey;

    GetX509(self, x509);
    if (!(pkey = X509_get_pubkey(x509))) { /* adds an reference */
        ossl_raise(eX509CertError, NULL);
    }

    return ossl_pkey_new(pkey); /* NO DUP - OK */
}
public_key = key → key click to toggle source
static VALUE
ossl_x509_set_public_key(VALUE self, VALUE key)
{
    X509 *x509;

    GetX509(self, x509);
    if (!X509_set_pubkey(x509, GetPKeyPtr(key))) { /* DUPs pkey */
        ossl_raise(eX509CertError, NULL);
    }

    return key;
}
serial → integer click to toggle source
static VALUE
ossl_x509_get_serial(VALUE self)
{
    X509 *x509;

    GetX509(self, x509);

    return asn1integer_to_num(X509_get_serialNumber(x509));
}
serial = integer → integer click to toggle source
static VALUE
ossl_x509_set_serial(VALUE self, VALUE num)
{
    X509 *x509;

    GetX509(self, x509);

    x509->cert_info->serialNumber =
        num_to_asn1integer(num, X509_get_serialNumber(x509));

    return num;
}
sign(key, digest) → self click to toggle source
static VALUE
ossl_x509_sign(VALUE self, VALUE key, VALUE digest)
{
    X509 *x509;
    EVP_PKEY *pkey;
    const EVP_MD *md;

    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
    md = GetDigestPtr(digest);
    GetX509(self, x509);
    if (!X509_sign(x509, pkey, md)) {
        ossl_raise(eX509CertError, NULL);
    }

    return self;
}
signature_algorithm → string click to toggle source
static VALUE
ossl_x509_get_signature_algorithm(VALUE self)
{
    X509 *x509;
    BIO *out;
    VALUE str;

    GetX509(self, x509);
    out = BIO_new(BIO_s_mem());
    if (!out) ossl_raise(eX509CertError, NULL);

    if (!i2a_ASN1_OBJECT(out, x509->cert_info->signature->algorithm)) {
        BIO_free(out);
        ossl_raise(eX509CertError, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}
subject → name click to toggle source
static VALUE
ossl_x509_get_subject(VALUE self)
{
    X509 *x509;
    X509_NAME *name;

    GetX509(self, x509);
    if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */
        ossl_raise(eX509CertError, NULL);
    }

    return ossl_x509name_new(name);
}
subject = name → name click to toggle source
static VALUE
ossl_x509_set_subject(VALUE self, VALUE subject)
{
    X509 *x509;

    GetX509(self, x509);
    if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */
        ossl_raise(eX509CertError, NULL);
    }

    return subject;
}
to_der → string click to toggle source
static VALUE
ossl_x509_to_der(VALUE self)
{
    X509 *x509;
    VALUE str;
    long len;
    unsigned char *p;

    GetX509(self, x509);
    if ((len = i2d_X509(x509, NULL)) <= 0)
        ossl_raise(eX509CertError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if (i2d_X509(x509, &p) <= 0)
        ossl_raise(eX509CertError, NULL);
    ossl_str_adjust(str, p);

    return str;
}
to_pem → string click to toggle source
static VALUE
ossl_x509_to_pem(VALUE self)
{
    X509 *x509;
    BIO *out;
    VALUE str;

    GetX509(self, x509);
    out = BIO_new(BIO_s_mem());
    if (!out) ossl_raise(eX509CertError, NULL);

    if (!PEM_write_bio_X509(out, x509)) {
        BIO_free(out);
        ossl_raise(eX509CertError, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}
Also aliased as: to_s
to_s() click to toggle source
Alias for: to_pem
to_text → string click to toggle source
static VALUE
ossl_x509_to_text(VALUE self)
{
    X509 *x509;
    BIO *out;
    VALUE str;

    GetX509(self, x509);

    out = BIO_new(BIO_s_mem());
    if (!out) ossl_raise(eX509CertError, NULL);

    if (!X509_print(out, x509)) {
        BIO_free(out);
        ossl_raise(eX509CertError, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}
verify(key) → true | false click to toggle source

Checks that cert signature is made with PRIVversion of this PUBLIC 'key'

static VALUE
ossl_x509_verify(VALUE self, VALUE key)
{
    X509 *x509;
    EVP_PKEY *pkey;
    int i;

    pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
    GetX509(self, x509);
    if ((i = X509_verify(x509, pkey)) < 0) {
        ossl_raise(eX509CertError, NULL);
    }
    if (i > 0) {
        return Qtrue;
    }

    return Qfalse;
}
version → integer click to toggle source
static VALUE
ossl_x509_get_version(VALUE self)
{
    X509 *x509;

    GetX509(self, x509);

    return LONG2NUM(X509_get_version(x509));
}
version = integer → integer click to toggle source
static VALUE
ossl_x509_set_version(VALUE self, VALUE version)
{
    X509 *x509;
    long ver;

    if ((ver = NUM2LONG(version)) < 0) {
        ossl_raise(eX509CertError, "version must be >= 0!");
    }
    GetX509(self, x509);
    if (!X509_set_version(x509, ver)) {
        ossl_raise(eX509CertError, NULL);
    }

    return version;
}


class OpenSSL::X509::CertificateError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::CertificateError

let rdoc know about mOSSL

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

eOSSLError


class OpenSSL::X509::Extension - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::Extension

In Files

  • ext/openssl/lib/openssl/x509.rb
  • ext/openssl/ossl_ssl_session.c

Parent

Object

Public Class Methods

OpenSSL::X509::Extension.new asn1 click to toggle source
OpenSSL::X509::Extension.new name, value
OpenSSL::X509::Extension.new name, value, critical

Creates an X509 extension.

The extension may be created from asn1 data or from an extension name and value. The name may be either an OID or an extension name. If critical is true the extension is marked critical.

static VALUE
ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE oid, value, critical;
    const unsigned char *p;
    X509_EXTENSION *ext, *x;

    GetX509Ext(self, ext);
    if(rb_scan_args(argc, argv, "12", &oid, &value, &critical) == 1){
        oid = ossl_to_der_if_possible(oid);
        StringValue(oid);
        p = (unsigned char *)RSTRING_PTR(oid);
        x = d2i_X509_EXTENSION(&ext, &p, RSTRING_LEN(oid));
        DATA_PTR(self) = ext;
        if(!x)
            ossl_raise(eX509ExtError, NULL);
        return self;
    }
    rb_funcall(self, rb_intern("oid="), 1, oid);
    rb_funcall(self, rb_intern("value="), 1, value);
    if(argc > 2) rb_funcall(self, rb_intern("critical="), 1, critical);

    return self;
}

Public Instance Methods

critical=(p1) click to toggle source
static VALUE
ossl_x509ext_set_critical(VALUE self, VALUE flag)
{
    X509_EXTENSION *ext;

    GetX509Ext(self, ext);
    X509_EXTENSION_set_critical(ext, RTEST(flag) ? 1 : 0);

    return flag;
}
critical?() click to toggle source
static VALUE
ossl_x509ext_get_critical(VALUE obj)
{
    X509_EXTENSION *ext;

    GetX509Ext(obj, ext);
    return X509_EXTENSION_get_critical(ext) ? Qtrue : Qfalse;
}
oid() click to toggle source
static VALUE
ossl_x509ext_get_oid(VALUE obj)
{
    X509_EXTENSION *ext;
    ASN1_OBJECT *extobj;
    BIO *out;
    VALUE ret;
    int nid;

    GetX509Ext(obj, ext);
    extobj = X509_EXTENSION_get_object(ext);
    if ((nid = OBJ_obj2nid(extobj)) != NID_undef)
        ret = rb_str_new2(OBJ_nid2sn(nid));
    else{
        if (!(out = BIO_new(BIO_s_mem())))
            ossl_raise(eX509ExtError, NULL);
        i2a_ASN1_OBJECT(out, extobj);
        ret = ossl_membio2str(out);
    }

    return ret;
}
oid=(p1) click to toggle source
static VALUE
ossl_x509ext_set_oid(VALUE self, VALUE oid)
{
    X509_EXTENSION *ext;
    ASN1_OBJECT *obj;
    char *s;

    s = StringValuePtr(oid);
    obj = OBJ_txt2obj(s, 0);
    if(!obj) obj = OBJ_txt2obj(s, 1);
    if(!obj) ossl_raise(eX509ExtError, NULL);
    GetX509Ext(self, ext);
    X509_EXTENSION_set_object(ext, obj);

    return oid;
}
to_a() click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 61
def to_a
  [ self.oid, self.value, self.critical? ]
end
to_der() click to toggle source
static VALUE
ossl_x509ext_to_der(VALUE obj)
{
    X509_EXTENSION *ext;
    unsigned char *p;
    long len;
    VALUE str;

    GetX509Ext(obj, ext);
    if((len = i2d_X509_EXTENSION(ext, NULL)) <= 0)
        ossl_raise(eX509ExtError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_X509_EXTENSION(ext, &p) < 0)
        ossl_raise(eX509ExtError, NULL);
    ossl_str_adjust(str, p);

    return str;
}
to_h() click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 57
def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false}
  {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?}
end
to_s() click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 50
def to_s # "oid = critical, value"
  str = self.oid
  str << " = "
  str << "critical, " if self.critical?
  str << self.value.gsub(/\n/, ", ")
end
value() click to toggle source
static VALUE
ossl_x509ext_get_value(VALUE obj)
{
    X509_EXTENSION *ext;
    BIO *out;
    VALUE ret;

    GetX509Ext(obj, ext);
    if (!(out = BIO_new(BIO_s_mem())))
        ossl_raise(eX509ExtError, NULL);
    if (!X509V3_EXT_print(out, ext, 0, 0))
        M_ASN1_OCTET_STRING_print(out, ext->value);
    ret = ossl_membio2str(out);

    return ret;
}
value=(p1) click to toggle source
static VALUE
ossl_x509ext_set_value(VALUE self, VALUE data)
{
    X509_EXTENSION *ext;
    ASN1_OCTET_STRING *asn1s;
    char *s;

    data = ossl_to_der_if_possible(data);
    StringValue(data);
    if(!(s = OPENSSL_malloc(RSTRING_LEN(data))))
        ossl_raise(eX509ExtError, "malloc error");
    memcpy(s, RSTRING_PTR(data), RSTRING_LEN(data));
    if(!(asn1s = ASN1_OCTET_STRING_new())){
        OPENSSL_free(s);
        ossl_raise(eX509ExtError, NULL);
    }
    if(!M_ASN1_OCTET_STRING_set(asn1s, s, RSTRING_LENINT(data))){
        OPENSSL_free(s);
        ASN1_OCTET_STRING_free(asn1s);
        ossl_raise(eX509ExtError, NULL);
    }
    OPENSSL_free(s);
    GetX509Ext(self, ext);
    X509_EXTENSION_set_data(ext, asn1s);

    return data;
}


class OpenSSL::X509::ExtensionError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::ExtensionError

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

eOSSLError


class OpenSSL::X509::ExtensionFactory - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::ExtensionFactory

In Files

  • ext/openssl/lib/openssl/x509.rb
  • ext/openssl/ossl_ssl_session.c

Parent

Object

Attributes

config[R]
crl[R]
issuer_certificate[R]
subject_certificate[R]
subject_request[R]

Public Class Methods

new(p1 = v1, p2 = v2, p3 = v3, p4 = v4) click to toggle source
static VALUE
ossl_x509extfactory_initialize(int argc, VALUE *argv, VALUE self)
{
    /*X509V3_CTX *ctx;*/
    VALUE issuer_cert, subject_cert, subject_req, crl;

    /*GetX509ExtFactory(self, ctx);*/

    rb_scan_args(argc, argv, "04",
                 &issuer_cert, &subject_cert, &subject_req, &crl);
    if (!NIL_P(issuer_cert))
        ossl_x509extfactory_set_issuer_cert(self, issuer_cert);
    if (!NIL_P(subject_cert))
        ossl_x509extfactory_set_subject_cert(self, subject_cert);
    if (!NIL_P(subject_req))
        ossl_x509extfactory_set_subject_req(self, subject_req);
    if (!NIL_P(crl))
        ossl_x509extfactory_set_crl(self, crl);

    return self;
}

Public Instance Methods

config=(p1) click to toggle source
static VALUE
ossl_x509extfactory_set_config(VALUE self, VALUE config)
{
    X509V3_CTX *ctx;
    CONF *conf;

    GetX509ExtFactory(self, ctx);
    rb_iv_set(self, "@config", config);
    conf = GetConfigPtr(config);  /* NO DUP NEEDED */
    X509V3_set_nconf(ctx, conf);

    return config;
}
create_ext(p1, p2, p3 = v3) click to toggle source

Array to X509_EXTENSION Structure:

“ln”, “value”, bool_critical

or

“sn”, “value”, bool_critical

or

“ln”, “critical,value”

or the same for sn

“ln”, “value”

> not critical

static VALUE
ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self)
{
    X509V3_CTX *ctx;
    X509_EXTENSION *ext;
    VALUE oid, value, critical, valstr, obj;
    int nid;
#ifdef HAVE_X509V3_EXT_NCONF_NID
    VALUE rconf;
    CONF *conf;
#else
    static LHASH *empty_lhash;
#endif

    rb_scan_args(argc, argv, "21", &oid, &value, &critical);
    StringValue(oid);
    StringValue(value);
    if(NIL_P(critical)) critical = Qfalse;

    nid = OBJ_ln2nid(RSTRING_PTR(oid));
    if(!nid) nid = OBJ_sn2nid(RSTRING_PTR(oid));
    if(!nid) ossl_raise(eX509ExtError, "unknown OID `%s'", RSTRING_PTR(oid));
    valstr = rb_str_new2(RTEST(critical) ? "critical," : "");
    rb_str_append(valstr, value);
    GetX509ExtFactory(self, ctx);
#ifdef HAVE_X509V3_EXT_NCONF_NID
    rconf = rb_iv_get(self, "@config");
    conf = NIL_P(rconf) ? NULL : GetConfigPtr(rconf);
    ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr));
#else
    if (!empty_lhash) empty_lhash = lh_new(NULL, NULL);
    ext = X509V3_EXT_conf_nid(empty_lhash, ctx, nid, RSTRING_PTR(valstr));
#endif
    if (!ext){
        ossl_raise(eX509ExtError, "%s = %s",
                   RSTRING_PTR(oid), RSTRING_PTR(value));
    }
    WrapX509Ext(cX509Ext, obj, ext);

    return obj;
}
create_ext_from_array(ary) click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 32
def create_ext_from_array(ary)
  raise ExtensionError, "unexpected array form" if ary.size > 3
  create_ext(ary[0], ary[1], ary[2])
end
create_ext_from_hash(hash) click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 44
def create_ext_from_hash(hash)
  create_ext(hash["oid"], hash["value"], hash["critical"])
end
create_ext_from_string(str) click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 37
def create_ext_from_string(str) # "oid = critical, value"
  oid, value = str.split(/=/, 2)
  oid.strip!
  value.strip!
  create_ext(oid, value)
end
create_extension(*arg) click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 24
def create_extension(*arg)
  if arg.size > 1
    create_ext(*arg)
  else
    send("create_ext_from_"+arg[0].class.name.downcase, arg[0])
  end
end
crl=(p1) click to toggle source
static VALUE
ossl_x509extfactory_set_crl(VALUE self, VALUE crl)
{
    X509V3_CTX *ctx;

    GetX509ExtFactory(self, ctx);
    rb_iv_set(self, "@crl", crl);
    ctx->crl = GetX509CRLPtr(crl); /* NO DUP NEEDED */

    return crl;
}
issuer_certificate=(p1) click to toggle source
static VALUE
ossl_x509extfactory_set_issuer_cert(VALUE self, VALUE cert)
{
    X509V3_CTX *ctx;

    GetX509ExtFactory(self, ctx);
    rb_iv_set(self, "@issuer_certificate", cert);
    ctx->issuer_cert = GetX509CertPtr(cert); /* NO DUP NEEDED */

    return cert;
}
subject_certificate=(p1) click to toggle source
static VALUE
ossl_x509extfactory_set_subject_cert(VALUE self, VALUE cert)
{
    X509V3_CTX *ctx;

    GetX509ExtFactory(self, ctx);
    rb_iv_set(self, "@subject_certificate", cert);
    ctx->subject_cert = GetX509CertPtr(cert); /* NO DUP NEEDED */

    return cert;
}
subject_request=(p1) click to toggle source
static VALUE
ossl_x509extfactory_set_subject_req(VALUE self, VALUE req)
{
    X509V3_CTX *ctx;

    GetX509ExtFactory(self, ctx);
    rb_iv_set(self, "@subject_request", req);
    ctx->subject_req = GetX509ReqPtr(req); /* NO DUP NEEDED */

    return req;
}


class OpenSSL::X509::Name - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::Name

An X.509 name represents a hostname, email address or other entity associated with a public key.

You can create a Name by parsing a distinguished name String or by supplying the distinguished name as an Array.

name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'

name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']]

In Files

  • ext/openssl/lib/openssl/x509.rb
  • ext/openssl/ossl_ssl_session.c

Parent

Object

Included Modules

  • Comparable

Constants

COMPAT

COMPAT

A flag for to_s.

Breaks the name returned into multiple lines if longer than 80 characters.

DEFAULT_OBJECT_TYPE

DEFAULT_OBJECT_TYPE

The default object type for name entries.

MULTILINE

MULTILINE

A flag for to_s.

Returns a multiline format.

OBJECT_TYPE_TEMPLATE

OBJECT_TYPE_TEMPLATE

The default object type template for name entries.

ONELINE

ONELINE

A flag for to_s.

Returns a more readable format than RFC2253.

RFC2253

RFC2253

A flag for to_s.

Returns an RFC2253 format name.

Public Class Methods

X509::Name.new → name click to toggle source
X509::Name.new(der) → name
X509::Name.new(distinguished_name) → name
X509::Name.new(distinguished_name, template) → name

Creates a new Name.

A name may be created from a DER encoded string der, an Array representing a distinguished_name or a distinguished_name along with a template.

name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']]

name = OpenSSL::X509::Name.new name.to_der

See #add_entry for a description of the distinguished_name Array's contents

static VALUE
ossl_x509name_initialize(int argc, VALUE *argv, VALUE self)
{
    X509_NAME *name;
    VALUE arg, template;

    GetX509Name(self, name);
    if (rb_scan_args(argc, argv, "02", &arg, &template) == 0) {
        return self;
    }
    else {
        VALUE tmp = rb_check_array_type(arg);
        if (!NIL_P(tmp)) {
            VALUE args;
            if(NIL_P(template)) template = OBJECT_TYPE_TEMPLATE;
            args = rb_ary_new3(2, self, template);
            rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, args);
        }
        else{
            const unsigned char *p;
            VALUE str = ossl_to_der_if_possible(arg);
            X509_NAME *x;
            StringValue(str);
            p = (unsigned char *)RSTRING_PTR(str);
            x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str));
            DATA_PTR(self) = name;
            if(!x){
                ossl_raise(eX509NameError, NULL);
            }
        }
    }

    return self;
}
parse(str, template=OBJECT_TYPE_TEMPLATE) click to toggle source
Alias for: parse_openssl
parse_openssl(str, template=OBJECT_TYPE_TEMPLATE) click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 147
def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
  ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
  self.new(ary, template)
end
Also aliased as: parse
parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE) click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 142
def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
  ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
  self.new(ary, template)
end

Public Instance Methods

<=>(p1) click to toggle source
Alias for: cmp
add_entry(oid, value [, type]) → self click to toggle source

Adds a new entry with the given oid and value to this name. The oid is an object identifier defined in ASN.1. Some common OIDs are:

C

Country Name

CN

Common Name

DC

Domain Component

O

Organization Name

OU

Organizational Unit Name

ST

State or Province Name

static
VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self)
{
    X509_NAME *name;
    VALUE oid, value, type;

    rb_scan_args(argc, argv, "21", &oid, &value, &type);
    StringValue(oid);
    StringValue(value);
    if(NIL_P(type)) type = rb_aref(OBJECT_TYPE_TEMPLATE, oid);
    GetX509Name(self, name);
    if (!X509_NAME_add_entry_by_txt(name, RSTRING_PTR(oid), NUM2INT(type),
                (const unsigned char *)RSTRING_PTR(value), RSTRING_LENINT(value), -1, 0)) {
        ossl_raise(eX509NameError, NULL);
    }

    return self;
}
cmp other → integer click to toggle source
<=> other → integer

Compares this Name with other and returns 0 if they are the same and -1 or +1 if they are greater or less than each other respectively.

static VALUE
ossl_x509name_cmp(VALUE self, VALUE other)
{
    int result;

    result = ossl_x509name_cmp0(self, other);
    if (result < 0) return INT2FIX(-1);
    if (result > 1) return INT2FIX(1);

    return INT2FIX(0);
}
Also aliased as: <=>
eql? other → boolean click to toggle source

Returns true if name and other refer to the same hash key.

static VALUE
ossl_x509name_eql(VALUE self, VALUE other)
{
    int result;

    if(CLASS_OF(other) != cX509Name) return Qfalse;
    result = ossl_x509name_cmp0(self, other);

    return (result == 0) ? Qtrue : Qfalse;
}
hash → integer click to toggle source

The hash value returned is suitable for use as a certificate's filename in a CA path.

static VALUE
ossl_x509name_hash(VALUE self)
{
    X509_NAME *name;
    unsigned long hash;

    GetX509Name(self, name);

    hash = X509_NAME_hash(name);

    return ULONG2NUM(hash);
}
hash_old → integer click to toggle source

Returns an MD5 based hash used in OpenSSL 0.9.X.

static VALUE
ossl_x509name_hash_old(VALUE self)
{
    X509_NAME *name;
    unsigned long hash;

    GetX509Name(self, name);

    hash = X509_NAME_hash_old(name);

    return ULONG2NUM(hash);
}
to_a → [[name, data, type], ...] click to toggle source

Returns an Array representation of the distinguished name suitable for passing to ::new

static VALUE
ossl_x509name_to_a(VALUE self)
{
    X509_NAME *name;
    X509_NAME_ENTRY *entry;
    int i,entries,nid;
    char long_name[512];
    const char *short_name;
    VALUE ary, vname, ret;

    GetX509Name(self, name);
    entries = X509_NAME_entry_count(name);
    if (entries < 0) {
        OSSL_Debug("name entries < 0!");
        return rb_ary_new();
    }
    ret = rb_ary_new2(entries);
    for (i=0; i<entries; i++) {
        if (!(entry = X509_NAME_get_entry(name, i))) {
            ossl_raise(eX509NameError, NULL);
        }
        if (!i2t_ASN1_OBJECT(long_name, sizeof(long_name), entry->object)) {
            ossl_raise(eX509NameError, NULL);
        }
        nid = OBJ_ln2nid(long_name);
        if (nid == NID_undef) {
            vname = rb_str_new2((const char *) &long_name);
        } else {
            short_name = OBJ_nid2sn(nid);
            vname = rb_str_new2(short_name); /*do not free*/
        }
        ary = rb_ary_new3(3,
                          vname,
                          rb_str_new((const char *)entry->value->data, entry->value->length),
                          INT2FIX(entry->value->type));
        rb_ary_push(ret, ary);
    }
    return ret;
}
to_der → string click to toggle source

Converts the name to DER encoding

static VALUE
ossl_x509name_to_der(VALUE self)
{
    X509_NAME *name;
    VALUE str;
    long len;
    unsigned char *p;

    GetX509Name(self, name);
    if((len = i2d_X509_NAME(name, NULL)) <= 0)
        ossl_raise(eX509NameError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_X509_NAME(name, &p) <= 0)
        ossl_raise(eX509NameError, NULL);
    ossl_str_adjust(str, p);

    return str;
}
to_s → string click to toggle source
to_s(flags) → string

Returns this name as a Distinguished Name string. flags may be one of:

  • OpenSSL::X509::Name::COMPAT

  • OpenSSL::X509::Name::RFC2253

  • OpenSSL::X509::Name::ONELINE

  • OpenSSL::X509::Name::MULTILINE

static VALUE
ossl_x509name_to_s(int argc, VALUE *argv, VALUE self)
{
    X509_NAME *name;
    VALUE flag, str;
    BIO *out;
    unsigned long iflag;

    rb_scan_args(argc, argv, "01", &flag);
    if (NIL_P(flag))
        return ossl_x509name_to_s_old(self);
    else iflag = NUM2ULONG(flag);
    if (!(out = BIO_new(BIO_s_mem())))
        ossl_raise(eX509NameError, NULL);
    GetX509Name(self, name);
    if (!X509_NAME_print_ex(out, name, 0, iflag)){
        BIO_free(out);
        ossl_raise(eX509NameError, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}


module OpenSSL::X509::Name::RFC2253DN - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenSSL::X509::Name::RFC2253DN

In Files

  • ext/openssl/lib/openssl/x509.rb

Constants

AttributeType
AttributeValue
HexChar
HexPair
HexString
Pair
QuoteChar
Special
StringChar
TypeAndValue

Public Instance Methods

expand_hexstring(str) click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 97
def expand_hexstring(str)
  return nil unless str
  der = str.gsub(HexPair){$&.to_i(16).chr }
  a1 = OpenSSL::ASN1.decode(der)
  return a1.value, a1.tag
end
expand_pair(str) click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 85
def expand_pair(str)
  return nil unless str
  return str.gsub(Pair){
    pair = $&
    case pair.size
    when 2 then pair[1,1]
    when 3 then Integer("0x#{pair[1,2]}").chr
    else raise OpenSSL::X509::NameError, "invalid pair: #{str}"
    end
  }
end
expand_value(str1, str2, str3) click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 104
def expand_value(str1, str2, str3)
  value = expand_pair(str1)
  value, tag = expand_hexstring(str2) unless value
  value = expand_pair(str3) unless value
  return value, tag
end
scan(dn) click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 111
def scan(dn)
  str = dn
  ary = []
  while true
    if md = TypeAndValue.match(str)
      remain = md.post_match
      type = md[1]
      value, tag = expand_value(md[2], md[3], md[4]) rescue nil
      if value
        type_and_value = [type, value]
        type_and_value.push(tag) if tag
        ary.unshift(type_and_value)
        if remain.length > 2 && remain[0] == ,
          str = remain[1..-1]
          next
        elsif remain.length > 2 && remain[0] == +
          raise OpenSSL::X509::NameError,
            "multi-valued RDN is not supported: #{dn}"
        elsif remain.empty?
          break
        end
      end
    end
    msg_dn = dn[0, dn.length - str.length] + " =>" + str
    raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}"
  end
  return ary
end


class OpenSSL::X509::NameError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::NameError

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

eOSSLError


class OpenSSL::X509::Request - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::Request

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

Object

Public Class Methods

new(p1 = v1) click to toggle source
static VALUE
ossl_x509req_initialize(int argc, VALUE *argv, VALUE self)
{
    BIO *in;
    X509_REQ *req, *x = DATA_PTR(self);
    VALUE arg;

    if (rb_scan_args(argc, argv, "01", &arg) == 0) {
        return self;
    }
    arg = ossl_to_der_if_possible(arg);
    in = ossl_obj2bio(arg);
    req = PEM_read_bio_X509_REQ(in, &x, NULL, NULL);
    DATA_PTR(self) = x;
    if (!req) {
        OSSL_BIO_reset(in);
        req = d2i_X509_REQ_bio(in, &x);
        DATA_PTR(self) = x;
    }
    BIO_free(in);
    if (!req) ossl_raise(eX509ReqError, NULL);

    return self;
}

Public Instance Methods

add_attribute(p1) click to toggle source
static VALUE
ossl_x509req_add_attribute(VALUE self, VALUE attr)
{
    X509_REQ *req;

    GetX509Req(self, req);
    if (!X509_REQ_add1_attr(req, DupX509AttrPtr(attr))) {
        ossl_raise(eX509ReqError, NULL);
    }

    return attr;
}
attributes() click to toggle source
static VALUE
ossl_x509req_get_attributes(VALUE self)
{
    X509_REQ *req;
    int count, i;
    X509_ATTRIBUTE *attr;
    VALUE ary;

    GetX509Req(self, req);

    count = X509_REQ_get_attr_count(req);
    if (count < 0) {
        OSSL_Debug("count < 0???");
        return rb_ary_new();
    }
    ary = rb_ary_new2(count);
    for (i=0; i<count; i++) {
        attr = X509_REQ_get_attr(req, i);
        rb_ary_push(ary, ossl_x509attr_new(attr));
    }

    return ary;
}
attributes=(p1) click to toggle source
static VALUE
ossl_x509req_set_attributes(VALUE self, VALUE ary)
{
    X509_REQ *req;
    X509_ATTRIBUTE *attr;
    int i;
    VALUE item;

    Check_Type(ary, T_ARRAY);
    for (i=0;i<RARRAY_LEN(ary); i++) {
        OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Attr);
    }
    GetX509Req(self, req);
    sk_X509_ATTRIBUTE_pop_free(req->req_info->attributes, X509_ATTRIBUTE_free);
    req->req_info->attributes = NULL;
    for (i=0;i<RARRAY_LEN(ary); i++) {
        item = RARRAY_PTR(ary)[i];
        attr = DupX509AttrPtr(item);
        if (!X509_REQ_add1_attr(req, attr)) {
            ossl_raise(eX509ReqError, NULL);
        }
    }
    return ary;
}
public_key() click to toggle source
static VALUE
ossl_x509req_get_public_key(VALUE self)
{
    X509_REQ *req;
    EVP_PKEY *pkey;

    GetX509Req(self, req);
    if (!(pkey = X509_REQ_get_pubkey(req))) { /* adds reference */
        ossl_raise(eX509ReqError, NULL);
    }

    return ossl_pkey_new(pkey); /* NO DUP - OK */
}
public_key=(p1) click to toggle source
static VALUE
ossl_x509req_set_public_key(VALUE self, VALUE key)
{
    X509_REQ *req;
    EVP_PKEY *pkey;

    GetX509Req(self, req);
    pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
    if (!X509_REQ_set_pubkey(req, pkey)) {
        ossl_raise(eX509ReqError, NULL);
    }

    return key;
}
sign(p1, p2) click to toggle source
static VALUE
ossl_x509req_sign(VALUE self, VALUE key, VALUE digest)
{
    X509_REQ *req;
    EVP_PKEY *pkey;
    const EVP_MD *md;

    GetX509Req(self, req);
    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
    md = GetDigestPtr(digest);
    if (!X509_REQ_sign(req, pkey, md)) {
        ossl_raise(eX509ReqError, NULL);
    }

    return self;
}
signature_algorithm() click to toggle source
static VALUE
ossl_x509req_get_signature_algorithm(VALUE self)
{
    X509_REQ *req;
    BIO *out;
    BUF_MEM *buf;
    VALUE str;

    GetX509Req(self, req);

    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eX509ReqError, NULL);
    }
    if (!i2a_ASN1_OBJECT(out, req->sig_alg->algorithm)) {
        BIO_free(out);
        ossl_raise(eX509ReqError, NULL);
    }
    BIO_get_mem_ptr(out, &buf);
    str = rb_str_new(buf->data, buf->length);
    BIO_free(out);
    return str;
}
subject() click to toggle source
static VALUE
ossl_x509req_get_subject(VALUE self)
{
    X509_REQ *req;
    X509_NAME *name;

    GetX509Req(self, req);
    if (!(name = X509_REQ_get_subject_name(req))) { /* NO DUP - don't free */
        ossl_raise(eX509ReqError, NULL);
    }

    return ossl_x509name_new(name);
}
subject=(p1) click to toggle source
static VALUE
ossl_x509req_set_subject(VALUE self, VALUE subject)
{
    X509_REQ *req;

    GetX509Req(self, req);
    /* DUPs name */
    if (!X509_REQ_set_subject_name(req, GetX509NamePtr(subject))) {
        ossl_raise(eX509ReqError, NULL);
    }

    return subject;
}
to_der() click to toggle source
static VALUE
ossl_x509req_to_der(VALUE self)
{
    X509_REQ *req;
    VALUE str;
    long len;
    unsigned char *p;

    GetX509Req(self, req);
    if ((len = i2d_X509_REQ(req, NULL)) <= 0)
        ossl_raise(eX509ReqError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if (i2d_X509_REQ(req, &p) <= 0)
        ossl_raise(eX509ReqError, NULL);
    ossl_str_adjust(str, p);

    return str;
}
to_pem() click to toggle source
static VALUE
ossl_x509req_to_pem(VALUE self)
{
    X509_REQ *req;
    BIO *out;
    BUF_MEM *buf;
    VALUE str;

    GetX509Req(self, req);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eX509ReqError, NULL);
    }
    if (!PEM_write_bio_X509_REQ(out, req)) {
        BIO_free(out);
        ossl_raise(eX509ReqError, NULL);
    }
    BIO_get_mem_ptr(out, &buf);
    str = rb_str_new(buf->data, buf->length);
    BIO_free(out);

    return str;
}
Also aliased as: to_s
to_s() click to toggle source
Alias for: to_pem
to_text() click to toggle source
static VALUE
ossl_x509req_to_text(VALUE self)
{
    X509_REQ *req;
    BIO *out;
    BUF_MEM *buf;
    VALUE str;

    GetX509Req(self, req);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eX509ReqError, NULL);
    }
    if (!X509_REQ_print(out, req)) {
        BIO_free(out);
        ossl_raise(eX509ReqError, NULL);
    }
    BIO_get_mem_ptr(out, &buf);
    str = rb_str_new(buf->data, buf->length);
    BIO_free(out);

    return str;
}
verify(p1) click to toggle source

Checks that cert signature is made with PRIVversion of this PUBLIC 'key'

static VALUE
ossl_x509req_verify(VALUE self, VALUE key)
{
    X509_REQ *req;
    EVP_PKEY *pkey;
    int i;

    GetX509Req(self, req);
    pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
    if ((i = X509_REQ_verify(req, pkey)) < 0) {
        ossl_raise(eX509ReqError, NULL);
    }
    if (i > 0) {
        return Qtrue;
    }

    return Qfalse;
}
version() click to toggle source
static VALUE
ossl_x509req_get_version(VALUE self)
{
    X509_REQ *req;
    long version;

    GetX509Req(self, req);
    version = X509_REQ_get_version(req);

    return LONG2FIX(version);
}
version=(p1) click to toggle source
static VALUE
ossl_x509req_set_version(VALUE self, VALUE version)
{
    X509_REQ *req;
    long ver;

    if ((ver = FIX2LONG(version)) < 0) {
        ossl_raise(eX509ReqError, "version must be >= 0!");
    }
    GetX509Req(self, req);
    if (!X509_REQ_set_version(req, ver)) {
        ossl_raise(eX509ReqError, NULL);
    }

    return version;
}


class OpenSSL::X509::RequestError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::RequestError

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

eOSSLError


class OpenSSL::X509::Revoked - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::Revoked

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

Object

Public Class Methods

new(*args) click to toggle source
static VALUE
ossl_x509revoked_initialize(int argc, VALUE *argv, VALUE self)
{
    /* EMPTY */
    return self;
}

Public Instance Methods

add_extension(p1) click to toggle source
static VALUE
ossl_x509revoked_add_extension(VALUE self, VALUE ext)
{
    X509_REVOKED *rev;

    GetX509Rev(self, rev);
    if(!X509_REVOKED_add_ext(rev, DupX509ExtPtr(ext), -1)) {
        ossl_raise(eX509RevError, NULL);
    }

    return ext;
}
extensions() click to toggle source

Gets X509v3 extensions as array of X509Ext objects

static VALUE
ossl_x509revoked_get_extensions(VALUE self)
{
    X509_REVOKED *rev;
    int count, i;
    X509_EXTENSION *ext;
    VALUE ary;

    GetX509Rev(self, rev);
    count = X509_REVOKED_get_ext_count(rev);
    if (count < 0) {
        OSSL_Debug("count < 0???");
        return rb_ary_new();
    }
    ary = rb_ary_new2(count);
    for (i=0; i<count; i++) {
        ext = X509_REVOKED_get_ext(rev, i);
        rb_ary_push(ary, ossl_x509ext_new(ext));
    }

    return ary;
}
extensions=(p1) click to toggle source

Sets X509_EXTENSIONs

static VALUE
ossl_x509revoked_set_extensions(VALUE self, VALUE ary)
{
    X509_REVOKED *rev;
    X509_EXTENSION *ext;
    int i;
    VALUE item;

    Check_Type(ary, T_ARRAY);
    for (i=0; i<RARRAY_LEN(ary); i++) {
        OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext);
    }
    GetX509Rev(self, rev);
    sk_X509_EXTENSION_pop_free(rev->extensions, X509_EXTENSION_free);
    rev->extensions = NULL;
    for (i=0; i<RARRAY_LEN(ary); i++) {
        item = RARRAY_PTR(ary)[i];
        ext = DupX509ExtPtr(item);
        if(!X509_REVOKED_add_ext(rev, ext, -1)) {
            ossl_raise(eX509RevError, NULL);
        }
    }

    return ary;
}
serial() click to toggle source
static VALUE
ossl_x509revoked_get_serial(VALUE self)
{
    X509_REVOKED *rev;

    GetX509Rev(self, rev);

    return asn1integer_to_num(rev->serialNumber);
}
serial=(p1) click to toggle source
static VALUE
ossl_x509revoked_set_serial(VALUE self, VALUE num)
{
    X509_REVOKED *rev;

    GetX509Rev(self, rev);
    rev->serialNumber = num_to_asn1integer(num, rev->serialNumber);

    return num;
}
time() click to toggle source
static VALUE
ossl_x509revoked_get_time(VALUE self)
{
    X509_REVOKED *rev;

    GetX509Rev(self, rev);

    return asn1time_to_time(rev->revocationDate);
}
time=(p1) click to toggle source
static VALUE
ossl_x509revoked_set_time(VALUE self, VALUE time)
{
    X509_REVOKED *rev;
    time_t sec;

    sec = time_to_time_t(time);
    GetX509Rev(self, rev);
    if (!X509_time_adj(rev->revocationDate, 0, &sec)) {
        ossl_raise(eX509RevError, NULL);
    }

    return time;
}


class OpenSSL::X509::RevokedError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::RevokedError

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

eOSSLError


class OpenSSL::X509::Store - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::Store

The X509 certificate store holds trusted CA certificates used to verify peer certificates.

The easiest way to create a useful certificate store is:

cert_store = OpenSSL::X509::Store.new
cert_store.set_default_paths

This will use your system's built-in certificates.

If your system does not have a default set of certificates you can obtain a set from Mozilla here: curl.haxx.se/docs/caextract.html (Note that this set does not have an HTTPS download option so you may wish to use the firefox-db2pem.sh script to extract the certificates from a local install to avoid man-in-the-middle attacks.)

After downloading or generating a cacert.pem from the above link you can create a certificate store from the pem file like this:

cert_store = OpenSSL::X509::Store.new
cert_store.add_file 'cacert.pem'

The certificate store can be used with an SSLSocket like this:

ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.cert_store = cert_store

tcp_socket = TCPSocket.open 'example.com', 443

ssl_socket = OpenSSL::SSL::SSLSocket.new tcp_socket, ssl_context

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

Object

Attributes

chain[R]
error[R]
error_string[R]
verify_callback[R]

Public Class Methods

X509::Store.new → store click to toggle source
static VALUE
ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
{
    X509_STORE *store;

/* BUG: This method takes any number of arguments but appears to ignore them. */
    GetX509Store(self, store);
    store->ex_data.sk = NULL;
    X509_STORE_set_verify_cb_func(store, ossl_verify_cb);
    ossl_x509store_set_vfy_cb(self, Qnil);

#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
    rb_iv_set(self, "@flags", INT2NUM(0));
    rb_iv_set(self, "@purpose", INT2NUM(0));
    rb_iv_set(self, "@trust", INT2NUM(0));
#endif

    /* last verification status */
    rb_iv_set(self, "@error", Qnil);
    rb_iv_set(self, "@error_string", Qnil);
    rb_iv_set(self, "@chain", Qnil);
    rb_iv_set(self, "@time", Qnil);

    return self;
}

Public Instance Methods

add_cert(cert) click to toggle source

Adds the OpenSSL::X509::Certificate cert to the certificate store.

static VALUE
ossl_x509store_add_cert(VALUE self, VALUE arg)
{
    X509_STORE *store;
    X509 *cert;

    cert = GetX509CertPtr(arg); /* NO NEED TO DUP */
    GetX509Store(self, store);
    if (X509_STORE_add_cert(store, cert) != 1){
        ossl_raise(eX509StoreError, NULL);
    }

    return self;
}
add_crl(p1) click to toggle source
static VALUE
ossl_x509store_add_crl(VALUE self, VALUE arg)
{
    X509_STORE *store;
    X509_CRL *crl;

    crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */
    GetX509Store(self, store);
    if (X509_STORE_add_crl(store, crl) != 1){
        ossl_raise(eX509StoreError, NULL);
    }

    return self;
}
add_file(file) → store click to toggle source

Adds the certificates in file to the certificate store. The file can contain multiple PEM-encoded certificates.

static VALUE
ossl_x509store_add_file(VALUE self, VALUE file)
{
    X509_STORE *store;
    X509_LOOKUP *lookup;
    char *path = NULL;

    if(file != Qnil){
        SafeStringValue(file);
        path = RSTRING_PTR(file);
    }
    GetX509Store(self, store);
    lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
    if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
    if(X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1){
        ossl_raise(eX509StoreError, NULL);
    }

    return self;
}
add_path(p1) click to toggle source
static VALUE
ossl_x509store_add_path(VALUE self, VALUE dir)
{
    X509_STORE *store;
    X509_LOOKUP *lookup;
    char *path = NULL;

    if(dir != Qnil){
        SafeStringValue(dir);
        path = RSTRING_PTR(dir);
    }
    GetX509Store(self, store);
    lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
    if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
    if(X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1){
        ossl_raise(eX509StoreError, NULL);
    }

    return self;
}
flags=(p1) click to toggle source
static VALUE
ossl_x509store_set_flags(VALUE self, VALUE flags)
{
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
    X509_STORE *store;
    long f = NUM2LONG(flags);

    GetX509Store(self, store);
    X509_STORE_set_flags(store, f);
#else
    rb_iv_set(self, "@flags", flags);
#endif

    return flags;
}
purpose=(p1) click to toggle source
static VALUE
ossl_x509store_set_purpose(VALUE self, VALUE purpose)
{
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
    X509_STORE *store;
    int p = NUM2INT(purpose);

    GetX509Store(self, store);
    X509_STORE_set_purpose(store, p);
#else
    rb_iv_set(self, "@purpose", purpose);
#endif

    return purpose;
}
set_default_path click to toggle source

Adds the default certificates to the certificate store. These certificates are loaded from the default configuration directory which can usually be determined by:

File.dirname OpenSSL::Config::DEFAULT_CONFIG_FILE
static VALUE
ossl_x509store_set_default_paths(VALUE self)
{
    X509_STORE *store;

    GetX509Store(self, store);
    if (X509_STORE_set_default_paths(store) != 1){
        ossl_raise(eX509StoreError, NULL);
    }

    return Qnil;
}
time=(p1) click to toggle source
static VALUE
ossl_x509store_set_time(VALUE self, VALUE time)
{
    rb_iv_set(self, "@time", time);
    return time;
}
trust=(p1) click to toggle source
static VALUE
ossl_x509store_set_trust(VALUE self, VALUE trust)
{
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
    X509_STORE *store;
    int t = NUM2INT(trust);

    GetX509Store(self, store);
    X509_STORE_set_trust(store, t);
#else
    rb_iv_set(self, "@trust", trust);
#endif

    return trust;
}
verify(p1, p2 = v2) click to toggle source
static VALUE
ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
{
    VALUE cert, chain;
    VALUE ctx, proc, result;

    rb_scan_args(argc, argv, "11", &cert, &chain);
    ctx = rb_funcall(cX509StoreContext, rb_intern("new"), 3, self, cert, chain);
    proc = rb_block_given_p() ?  rb_block_proc() :
           rb_iv_get(self, "@verify_callback");
    rb_iv_set(ctx, "@verify_callback", proc);
    result = rb_funcall(ctx, rb_intern("verify"), 0);

    rb_iv_set(self, "@error", ossl_x509stctx_get_err(ctx));
    rb_iv_set(self, "@error_string", ossl_x509stctx_get_err_string(ctx));
    rb_iv_set(self, "@chain", ossl_x509stctx_get_chain(ctx));

    return result;
}
verify_callback=(p1) click to toggle source

General callback for OpenSSL verify

static VALUE
ossl_x509store_set_vfy_cb(VALUE self, VALUE cb)
{
    X509_STORE *store;

    GetX509Store(self, store);
    X509_STORE_set_ex_data(store, ossl_verify_cb_idx, (void*)cb);
    rb_iv_set(self, "@verify_callback", cb);

    return cb;
}


class OpenSSL::X509::StoreContext - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::StoreContext

let rdoc know about mOSSL

In Files

  • ext/openssl/lib/openssl/x509.rb
  • ext/openssl/ossl_ssl_session.c

Parent

Object

Public Instance Methods

cleanup() click to toggle source
# File ext/openssl/lib/openssl/x509.rb, line 157
def cleanup
  warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE
end


class OpenSSL::X509::StoreError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenSSL::X509::StoreError

let rdoc know about mOSSL

In Files

  • ext/openssl/ossl_ssl_session.c

Parent

eOSSLError


class OpenStruct - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenStruct

An OpenStruct is a data structure, similar to a Hash, that allows the definition of arbitrary attributes with their accompanying values. This is accomplished by using Ruby's metaprogramming to define methods on the class itself.

Examples:

require 'ostruct'

person = OpenStruct.new
person.name    = "John Smith"
person.age     = 70
person.pension = 300

puts person.name     # -> "John Smith"
puts person.age      # -> 70
puts person.address  # -> nil

An OpenStruct employs a Hash internally to store the methods and values and can even be initialized with one:

australia = OpenStruct.new(:country => "Australia", :population => 20_000_000)
p australia   # -> <OpenStruct country="Australia" population=20000000>

Hash keys with spaces or characters that would normally not be able to use for method calls (e.g. ()[]*) will not be immediately available on the OpenStruct object as a method for retrieval or assignment, but can be still be reached through the Object#send method.

measurements = OpenStruct.new("length (in inches)" => 24)
measurements.send("length (in inches)")  # -> 24

data_point = OpenStruct.new(:queued? => true)
data_point.queued?                       # -> true
data_point.send("queued?=",false)
data_point.queued?                       # -> false

Removing the presence of a method requires the execution the #delete_field method as setting the property value to nil will not remove the method.

first_pet = OpenStruct.new(:name => 'Rowdy', :owner => 'John Smith')
first_pet.owner = nil
second_pet = OpenStruct.new(:name => 'Rowdy')

first_pet == second_pet   # -> false

first_pet.delete_field(:owner)
first_pet == second_pet   # -> true

Implementation:

An OpenStruct utilizes Ruby's method lookup structure to and find and define the necessary methods for properties. This is accomplished through the method method_missing and define_method.

This should be a consideration if there is a concern about the performance of the objects that are created, as there is much more overhead in the setting of these properties compared to using a Hash or a Struct.

OpenStruct serialization/deserialization

In Files

  • lib/ostruct.rb
  • ext/json/lib/json/add/ostruct.rb

Parent

Object

Public Class Methods

json_create(object) click to toggle source

Deserializes JSON string by constructing new Struct object with values v serialized by to_json.

# File ext/json/lib/json/add/ostruct.rb, line 11
def self.json_create(object)
  new(object['t'] || object[:t])
end
new(hash=nil) click to toggle source

Creates a new OpenStruct object. By default, the resulting OpenStruct object will have no attributes.

The optional hash, if given, will generate attributes and values (can be a Hash, an OpenStruct or a Struct). For example:

require 'ostruct'
hash = { "country" => "Australia", :population => 20_000_000 }
data = OpenStruct.new(hash)

p data        # -> <OpenStruct country="Australia" population=20000000>

# File lib/ostruct.rb, line 87
def initialize(hash=nil)
  @table = {}
  if hash
    hash.each_pair do |k, v|
      k = k.to_sym
      @table[k] = v
      new_ostruct_member(k)
    end
  end
end

Public Instance Methods

==(other) click to toggle source

Compares this object and other for equality. An OpenStruct is equal to other when other is an OpenStruct and the two objects' Hash tables are equal.

# File lib/ostruct.rb, line 263
def ==(other)
  return false unless other.kind_of?(OpenStruct)
  @table == other.table
end
[](name) click to toggle source

Returns the value of a member.

person = OpenStruct.new('name' => 'John Smith', 'age' => 70)
person[:age] # => 70, same as ostruct.age

# File lib/ostruct.rb, line 196
def [](name)
  @table[name.to_sym]
end
[]=(name, value) click to toggle source

Sets the value of a member.

person = OpenStruct.new('name' => 'John Smith', 'age' => 70)
person[:age] = 42 # => equivalent to ostruct.age = 42
person.age # => 42

# File lib/ostruct.rb, line 207
def []=(name, value)
  modifiable[new_ostruct_member(name)] = value
end
as_json(*) click to toggle source

Returns a hash, that will be turned into a JSON object and represent this object.

# File ext/json/lib/json/add/ostruct.rb, line 17
def as_json(*)
  klass = self.class.name
  klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
  {
    JSON.create_id => klass,
    't'            => table,
  }
end
delete_field(name) click to toggle source

Remove the named field from the object. Returns the value that the field contained if it was defined.

require 'ostruct'

person = OpenStruct.new('name' => 'John Smith', 'age' => 70)

person.delete_field('name')  # => 'John Smith'

# File lib/ostruct.rb, line 221
def delete_field(name)
  sym = name.to_sym
  singleton_class.__send__(:remove_method, sym, "#{name}=")
  @table.delete sym
end
each_pair() { |p| ... } click to toggle source

Yields all attributes (as a symbol) along with the corresponding values or returns an enumerator if not block is given. Example:

require 'ostruct'
data = OpenStruct.new("country" => "Australia", :population => 20_000_000)
data.each_pair.to_a  # => [[:country, "Australia"], [:population, 20000000]]

# File lib/ostruct.rb, line 127
def each_pair
  return to_enum __method__ unless block_given?
  @table.each_pair{|p| yield p}
end
eql?(other) click to toggle source

Compares this object and other for equality. An OpenStruct is eql? to other when other is an OpenStruct and the two objects' Hash tables are eql?.

# File lib/ostruct.rb, line 273
def eql?(other)
  return false unless other.kind_of?(OpenStruct)
  @table.eql?(other.table)
end
hash() click to toggle source

Compute a hash-code for this OpenStruct. Two hashes with the same content will have the same hash code (and will be eql?).

# File lib/ostruct.rb, line 281
def hash
  @table.hash
end
initialize_copy(orig) click to toggle source

Duplicate an OpenStruct object members.

# File lib/ostruct.rb, line 99
def initialize_copy(orig)
  super
  @table = @table.dup
  @table.each_key{|key| new_ostruct_member(key)}
end
inspect() click to toggle source

Returns a string containing a detailed summary of the keys and values.

# File lib/ostruct.rb, line 232
def inspect
  str = "#<#{self.class}"

  ids = (Thread.current[InspectKey] ||= [])
  if ids.include?(object_id)
    return str << ' ...>'
  end

  ids << object_id
  begin
    first = true
    for k,v in @table
      str << "," unless first
      first = false
      str << " #{k}=#{v.inspect}"
    end
    return str << '>'
  ensure
    ids.pop
  end
end
Also aliased as: to_s
marshal_dump() click to toggle source

Provides marshalling support for use by the Marshal library.

# File lib/ostruct.rb, line 135
def marshal_dump
  @table
end
marshal_load(x) click to toggle source

Provides marshalling support for use by the Marshal library.

# File lib/ostruct.rb, line 142
def marshal_load(x)
  @table = x
  @table.each_key{|key| new_ostruct_member(key)}
end
to_h() click to toggle source

Converts the OpenStruct to a hash with keys representing each attribute (as symbols) and their corresponding values Example:

require 'ostruct'
data = OpenStruct.new("country" => "Australia", :population => 20_000_000)
data.to_h   # => {:country => "Australia", :population => 20000000 }

# File lib/ostruct.rb, line 114
def to_h
  @table.dup
end
to_json(*args) click to toggle source

Stores class name (OpenStruct) with this struct's values v as a JSON string.

# File ext/json/lib/json/add/ostruct.rb, line 28
def to_json(*args)
  as_json.to_json(*args)
end
to_s() click to toggle source
Alias for: inspect

Protected Instance Methods

modifiable() click to toggle source

Used internally to check if the OpenStruct is able to be modified before granting access to the internal Hash table to be modified.

# File lib/ostruct.rb, line 151
def modifiable
  begin
    @modifiable = true
  rescue
    raise TypeError, "can't modify frozen #{self.class}", caller(3)
  end
  @table
end
new_ostruct_member(name) click to toggle source

Used internally to defined properties on the OpenStruct. It does this by using the metaprogramming function define_singleton_method for both the getter method and the setter method.

# File lib/ostruct.rb, line 166
def new_ostruct_member(name)
  name = name.to_sym
  unless respond_to?(name)
    define_singleton_method(name) { @table[name] }
    define_singleton_method("#{name}=") { |x| modifiable[name] = x }
  end
  name
end


module OpenURI - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenURI

OpenURI is an easy-to-use wrapper for Net::HTTP, Net::HTTPS and Net::FTP.

Example

It is possible to open an http, https or ftp URL as though it were a file:

open("http://www.ruby-lang.org/") {|f|
  f.each_line {|line| p line}
}

The opened file has several getter methods for its meta-information, as follows, since it is extended by OpenURI::Meta.

open("http://www.ruby-lang.org/en") {|f|
  f.each_line {|line| p line}
  p f.base_uri         # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
  p f.content_type     # "text/html"
  p f.charset          # "iso-8859-1"
  p f.content_encoding # []
  p f.last_modified    # Thu Dec 05 02:45:02 UTC 2002
}

Additional header fields can be specified by an optional hash argument.

open("http://www.ruby-lang.org/en/",
  "User-Agent" => "Ruby/#{RUBY_VERSION}",
  "From" => "foo@bar.invalid",
  "Referer" => "http://www.ruby-lang.org/") {|f|
  # ...
}

The environment variables such as http_proxy, https_proxy and ftp_proxy are in effect by default. Here we disable proxy:

open("http://www.ruby-lang.org/en/", :proxy => nil) {|f|
  # ...
}

See OpenURI::OpenRead#open and Kernel#open for more on available options.

URI objects can be opened in a similar way.

uri = URI.parse("http://www.ruby-lang.org/en/")
uri.open {|f|
  # ...
}

URI objects can be read directly. The returned string is also extended by OpenURI::Meta.

str = uri.read
p str.base_uri
Author

Tanaka Akira <akr@m17n.org>

In Files

  • lib/open-uri.rb

Constants

Options


class OpenURI::HTTPError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenURI::HTTPError

In Files

  • lib/open-uri.rb

Parent

StandardError

Attributes

io[R]

Public Class Methods

new(message, io) click to toggle source
# File lib/open-uri.rb, line 358
def initialize(message, io)
  super(message)
  @io = io
end


class OpenURI::HTTPRedirect - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OpenURI::HTTPRedirect

Raised on redirection, only occurs when redirect option for HTTP is false.

In Files

  • lib/open-uri.rb

Parent

OpenURI::HTTPError

Attributes

uri[R]

Public Class Methods

new(message, io, uri) click to toggle source
# File lib/open-uri.rb, line 368
def initialize(message, io, uri)
  super(message, io)
  @uri = uri
end


module OpenURI::Meta - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenURI::Meta

Mixin for holding meta-information.

In Files

  • lib/open-uri.rb

Attributes

base_uri[RW]

returns a URI that is the base of relative URIs in the data. It may differ from the URI supplied by a user due to redirection.

meta[R]

returns a Hash that represents header fields. The Hash keys are downcased for canonicalization.

status[RW]

returns an Array that consists of status code and message.

Public Instance Methods

charset() { || ... } click to toggle source

returns a charset parameter in Content-Type field. It is downcased for canonicalization.

If charset parameter is not given but a block is given, the block is called and its result is returned. It can be used to guess charset.

If charset parameter and block is not given, nil is returned except text type in HTTP. In that case, “iso-8859-1” is returned as defined by RFC2616 3.7.1.

# File lib/open-uri.rb, line 508
def charset
  type, *parameters = content_type_parse
  if pair = parameters.assoc('charset')
    pair.last.downcase
  elsif block_given?
    yield
  elsif type && %r{\Atext/} =~ type &&
        @base_uri && /\Ahttp\z/ =~ @base_uri.scheme
    "iso-8859-1" # RFC2616 3.7.1
  else
    nil
  end
end
content_encoding() click to toggle source

Returns a list of encodings in Content-Encoding field as an array of strings.

The encodings are downcased for canonicalization.

# File lib/open-uri.rb, line 526
def content_encoding
  v = @meta['content-encoding']
  if v && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*} =~ v
    v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase}
  else
    []
  end
end
content_type() click to toggle source

returns “type/subtype” which is MIME Content-Type. It is downcased for canonicalization. Content-Type parameters are stripped.

# File lib/open-uri.rb, line 493
def content_type
  type, *_ = content_type_parse
  type || 'application/octet-stream'
end
last_modified() click to toggle source

returns a Time that represents the Last-Modified field.

# File lib/open-uri.rb, line 456
def last_modified
  if v = @meta['last-modified']
    Time.httpdate(v)
  else
    nil
  end
end


module OpenURI::OpenRead - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OpenURI::OpenRead

Mixin for HTTP and FTP URIs.

In Files

  • lib/open-uri.rb

Public Instance Methods

open(*rest, &block) click to toggle source

#open provides `open' for URI::HTTP and URI::FTP.

#open takes optional 3 arguments as:

OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }]

#open returns an IO-like object if block is not given. Otherwise it yields the IO object and return the value of the block. The IO object is extended with OpenURI::Meta.

mode and perm are the same as Kernel#open.

However, mode must be read mode because #open doesn't support write mode (yet). Also perm is ignored because it is meaningful only for file creation.

options must be a hash.

Each option with a string key specifies an extra header field for HTTP. I.e., it is ignored for FTP without HTTP proxy.

The hash may include other options, where keys are symbols:

:proxy

Synopsis:

:proxy => "http://proxy.foo.com:8000/"
:proxy => URI.parse("http://proxy.foo.com:8000/")
:proxy => true
:proxy => false
:proxy => nil

If :proxy option is specified, the value should be String, URI, boolean or nil.

When String or URI is given, it is treated as proxy URI.

When true is given or the option itself is not specified, environment variable `scheme_proxy' is examined. `scheme' is replaced by `http', `https' or `ftp'.

When false or nil is given, the environment variables are ignored and connection will be made to a server directly.

:proxy_http_basic_authentication

Synopsis:

:proxy_http_basic_authentication =>
  ["http://proxy.foo.com:8000/", "proxy-user", "proxy-password"]
:proxy_http_basic_authentication =>
  [URI.parse("http://proxy.foo.com:8000/"),
   "proxy-user", "proxy-password"]

If :proxy option is specified, the value should be an Array with 3 elements. It should contain a proxy URI, a proxy user name and a proxy password. The proxy URI should be a String, an URI or nil. The proxy user name and password should be a String.

If nil is given for the proxy URI, this option is just ignored.

If :proxy and :proxy_http_basic_authentication is specified, ArgumentError is raised.

:http_basic_authentication

Synopsis:

:http_basic_authentication=>[user, password]

If :http_basic_authentication is specified, the value should be an array which contains 2 strings: username and password. It is used for HTTP Basic authentication defined by RFC 2617.

:content_length_proc

Synopsis:

:content_length_proc => lambda {|content_length| ... }

If :content_length_proc option is specified, the option value procedure is called before actual transfer is started. It takes one argument, which is expected content length in bytes.

If two or more transfer is done by HTTP redirection, the procedure is called only one for a last transfer.

When expected content length is unknown, the procedure is called with nil. This happens when the HTTP response has no Content-Length header.

:progress_proc

Synopsis:

:progress_proc => lambda {|size| ...}

If :progress_proc option is specified, the proc is called with one argument each time when `open' gets content fragment from network. The argument size is the accumulated transferred size in bytes.

If two or more transfer is done by HTTP redirection, the procedure is called only one for a last transfer.

:progress_proc and :content_length_proc are intended to be used for progress bar. For example, it can be implemented as follows using Ruby/ProgressBar.

pbar = nil
open("http://...",
  :content_length_proc => lambda {|t|
    if t && 0 < t
      pbar = ProgressBar.new("...", t)
      pbar.file_transfer_mode
    end
  },
  :progress_proc => lambda {|s|
    pbar.set s if pbar
  }) {|f| ... }
:read_timeout

Synopsis:

:read_timeout=>nil     (no timeout)
:read_timeout=>10      (10 second)

:read_timeout option specifies a timeout of read for http connections.

:ssl_ca_cert

Synopsis:

:ssl_ca_cert=>filename

:ssl_ca_cert is used to specify CA certificate for SSL. If it is given, default certificates are not used.

:ssl_verify_mode

Synopsis:

:ssl_verify_mode=>mode

:ssl_verify_mode is used to specify openssl verify mode.

:ftp_active_mode

Synopsis:

:ftp_active_mode=>bool

:ftp_active_mode => true is used to make ftp active mode. Ruby 1.9 uses passive mode by default. Note that the active mode is default in Ruby 1.8 or prior.

:redirect

Synopsis:

:redirect=>bool

:redirect is true by default. :redirect => false is used to disable all HTTP redirects.

OpenURI::HTTPRedirect exception raised on redirection. Using true also means that redirections between http and ftp are permitted.

# File lib/open-uri.rb, line 688
def open(*rest, &block)
  OpenURI.open_uri(self, *rest, &block)
end
read(options={}) click to toggle source

#read) reads a content referenced by self and returns the content as string. The string is extended with OpenURI::Meta. The argument options is same as #open.

# File lib/open-uri.rb, line 696
def read(options={})
  self.open(options) {|f|
    str = f.read
    Meta.init str, f
    str
  }
end


class OptionParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser

OptionParser

Introduction

OptionParser is a class for command-line option analysis. It is much more advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented solution.

Features

  1. The argument specification and the code to handle it are written in the same place.

  2. It can output an option summary; you don't need to maintain this string separately.

  3. Optional and mandatory arguments are specified very gracefully.

  4. Arguments can be automatically converted to a specified class.

  5. Arguments can be restricted to a certain set.

All of these features are demonstrated in the examples below. See make_switch for full documentation.

Minimal example

require 'optparse'

options = {}
OptionParser.new do |opts|
  opts.banner = "Usage: example.rb [options]"

  opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
    options[:verbose] = v
  end
end.parse!

p options
p ARGV

Complete example

The following example is a complete Ruby program. You can run it and see the effect of specifying various options. This is probably the best way to learn the features of optparse.

require 'optparse'
require 'optparse/time'
require 'ostruct'
require 'pp'

class OptparseExample

  CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
  CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }

  #
  # Return a structure describing the options.
  #
  def self.parse(args)
    # The options specified on the command line will be collected in *options*.
    # We set default values here.
    options = OpenStruct.new
    options.library = []
    options.inplace = false
    options.encoding = "utf8"
    options.transfer_type = :auto
    options.verbose = false

    opt_parser = OptionParser.new do |opts|
      opts.banner = "Usage: example.rb [options]"

      opts.separator ""
      opts.separator "Specific options:"

      # Mandatory argument.
      opts.on("-r", "--require LIBRARY",
              "Require the LIBRARY before executing your script") do |lib|
        options.library << lib
      end

      # Optional argument; multi-line description.
      opts.on("-i", "--inplace [EXTENSION]",
              "Edit ARGV files in place",
              "  (make backup if EXTENSION supplied)") do |ext|
        options.inplace = true
        options.extension = ext || ''
        options.extension.sub!(/\A\.?(?=.)/, ".")  # Ensure extension begins with dot.
      end

      # Cast 'delay' argument to a Float.
      opts.on("--delay N", Float, "Delay N seconds before executing") do |n|
        options.delay = n
      end

      # Cast 'time' argument to a Time object.
      opts.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
        options.time = time
      end

      # Cast to octal integer.
      opts.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger,
              "Specify record separator (default \\0)") do |rs|
        options.record_separator = rs
      end

      # List of arguments.
      opts.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
        options.list = list
      end

      # Keyword completion.  We are specifying a specific set of arguments (CODES
      # and CODE_ALIASES - notice the latter is a Hash), and the user may provide
      # the shortest unambiguous text.
      code_list = (CODE_ALIASES.keys + CODES).join(',')
      opts.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
              "  (#{code_list})") do |encoding|
        options.encoding = encoding
      end

      # Optional argument with keyword completion.
      opts.on("--type [TYPE]", [:text, :binary, :auto],
              "Select transfer type (text, binary, auto)") do |t|
        options.transfer_type = t
      end

      # Boolean switch.
      opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
        options.verbose = v
      end

      opts.separator ""
      opts.separator "Common options:"

      # No argument, shows at tail.  This will print an options summary.
      # Try it and see!
      opts.on_tail("-h", "--help", "Show this message") do
        puts opts
        exit
      end

      # Another typical switch to print the version.
      opts.on_tail("--version", "Show version") do
        puts OptionParser::Version.join('.')
        exit
      end
    end

    opt_parser.parse!(args)
    options
  end  # parse()

end  # class OptparseExample

options = OptparseExample.parse(ARGV)
pp options
pp ARGV

Shell Completion

For modern shells (e.g. bash, zsh, etc.), you can use shell completion for command line options.

Further documentation

The above examples should be enough to learn how to use this class. If you have any questions, file a ticket at bugs.ruby-lang.org.

In Files

  • lib/optparse.rb

Parent

Object

Public Class Methods

accept(*args, &blk) click to toggle source

See accept.

# File lib/optparse.rb, line 922
def self.accept(*args, &blk) top.accept(*args, &blk) end
each_const(path, base = ::Object) click to toggle source
# File lib/optparse/version.rb, line 49
def each_const(path, base = ::Object)
  path.split(/::|\//).inject(base) do |klass, name|
    raise NameError, path unless Module === klass
    klass.constants.grep(/#{name}/) do |c|
      klass.const_defined?(c) or next
      c = klass.const_get(c)
    end
  end
end
getopts(*args) click to toggle source

See getopts.

# File lib/optparse.rb, line 1506
def self.getopts(*args)
  new.getopts(*args)
end
inc(arg, default = nil) click to toggle source

Returns an incremented value of default according to arg.

# File lib/optparse.rb, line 858
def self.inc(arg, default = nil)
  case arg
  when Integer
    arg.nonzero?
  when nil
    default.to_i + 1
  end
end
new(banner = nil, width = 32, indent = ' ' * 4) { |self| ... } click to toggle source

Initializes the instance and yields itself if called with a block.

banner

Banner message.

width

Summary width.

indent

Summary indent.

# File lib/optparse.rb, line 877
def initialize(banner = nil, width = 32, indent = ' ' * 4)
  @stack = [DefaultList, List.new, List.new]
  @program_name = nil
  @banner = banner
  @summary_width = width
  @summary_indent = indent
  @default_argv = ARGV
  add_officious
  yield self if block_given?
end
reject(*args, &blk) click to toggle source

See reject.

# File lib/optparse.rb, line 935
def self.reject(*args, &blk) top.reject(*args, &blk) end
search_const(klass, name) { |klass, cname, const| ... } click to toggle source
# File lib/optparse/version.rb, line 59
def search_const(klass, name)
  klasses = [klass]
  while klass = klasses.shift
    klass.constants.each do |cname|
      klass.const_defined?(cname) or next
      const = klass.const_get(cname)
      yield klass, cname, const if name === cname
      klasses << const if Module === const and const != ::Object
    end
  end
end
show_version(*pkgs) click to toggle source
# File lib/optparse/version.rb, line 4
def show_version(*pkgs)
  progname = ARGV.options.program_name
  result = false
  show = proc do |klass, cname, version|
    str = "#{progname}"
    unless klass == ::Object and cname == :VERSION
      version = version.join(".") if Array === version
      str << ": #{klass}" unless klass == Object
      str << " version #{version}"
    end
    [:Release, :RELEASE].find do |rel|
      if klass.const_defined?(rel)
        str << " (#{klass.const_get(rel)})"
      end
    end
    puts str
    result = true
  end
  if pkgs.size == 1 and pkgs[0] == "all"
    self.search_const(::Object, /\AV(?:ERSION|ersion)\z/) do |klass, cname, version|
      unless cname[1] == e and klass.const_defined?(:Version)
        show.call(klass, cname.intern, version)
      end
    end
  else
    pkgs.each do |pkg|
      begin
        pkg = pkg.split(/::|\//).inject(::Object) {|m, c| m.const_get(c)}
        v = case
            when pkg.const_defined?(:Version)
              pkg.const_get(n = :Version)
            when pkg.const_defined?(:VERSION)
              pkg.const_get(n = :VERSION)
            else
              n = nil
              "unknown"
            end
        show.call(pkg, n, v)
      rescue NameError
      end
    end
  end
  result
end
terminate(arg = nil) click to toggle source
# File lib/optparse.rb, line 902
def self.terminate(arg = nil)
  throw :terminate, arg
end
top() click to toggle source
# File lib/optparse.rb, line 907
def self.top() DefaultList end
with(*args, &block) click to toggle source

Initializes a new instance and evaluates the optional block in context of the instance. Arguments args are passed to new, see there for description of parameters.

This method is deprecated, its behavior corresponds to the older new method.

# File lib/optparse.rb, line 849
def self.with(*args, &block)
  opts = new(*args)
  opts.instance_eval(&block)
  opts
end

Public Instance Methods

abort(mesg = $!) click to toggle source
# File lib/optparse.rb, line 1016
def abort(mesg = $!)
  super("#{program_name}: #{mesg}")
end
accept(*args, &blk) click to toggle source

Directs to accept specified class t. The argument string is passed to the block in which it should be converted to the desired class.

t

Argument class specifier, any object including Class.

pat

Pattern for argument, defaults to t if it responds to match.

accept(t, pat, &block)
# File lib/optparse.rb, line 918
def accept(*args, &blk) top.accept(*args, &blk) end
banner() click to toggle source

Heading banner preceding summary.

# File lib/optparse.rb, line 960
def banner
  unless @banner
    @banner = "Usage: #{program_name} [options]"
    visit(:add_banner, @banner)
  end
  @banner
end
base() click to toggle source

Subject of on_tail.

# File lib/optparse.rb, line 1030
def base
  @stack[1]
end
candidate(word) click to toggle source
# File lib/optparse.rb, line 1553
def candidate(word)
  list = []
  case word
  when /\A--/
    word, arg = word.split(/=/, 2)
    argpat = Completion.regexp(arg, false) if arg and !arg.empty?
    long = true
  when /\A-(!-)/
    short = true
  when /\A-/
    long = short = true
  end
  pat = Completion.regexp(word, true)
  visit(:each_option) do |opt|
    next unless Switch === opt
    opts = (long ? opt.long : []) + (short ? opt.short : [])
    opts = Completion.candidate(word, true, pat, &opts.method(:each)).map(&:first) if pat
    if /\A=/ =~ opt.arg
      opts.map! {|sw| sw + "="}
      if arg and CompletingHash === opt.pattern
        if opts = opt.pattern.candidate(arg, false, argpat)
          opts.map!(&:last)
        end
      end
    end
    list.concat(opts)
  end
  list
end
def_head_option(*opts, &block) click to toggle source
Alias for: define_head
def_option(*opts, &block) click to toggle source
Alias for: define
def_tail_option(*opts, &block) click to toggle source
Alias for: define_tail
define(*opts, &block) click to toggle source
# File lib/optparse.rb, line 1279
def define(*opts, &block)
  top.append(*(sw = make_switch(opts, block)))
  sw[0]
end
Also aliased as: def_option
define_head(*opts, &block) click to toggle source
# File lib/optparse.rb, line 1294
def define_head(*opts, &block)
  top.prepend(*(sw = make_switch(opts, block)))
  sw[0]
end
Also aliased as: def_head_option
define_tail(*opts, &block) click to toggle source
# File lib/optparse.rb, line 1308
def define_tail(*opts, &block)
  base.append(*(sw = make_switch(opts, block)))
  sw[0]
end
Also aliased as: def_tail_option
environment(env = File.basename($0, '.*')) click to toggle source

Parses environment variable env or its uppercase with splitting like a shell.

env defaults to the basename of the program.

# File lib/optparse.rb, line 1610
def environment(env = File.basename($0, '.*'))
  env = ENV[env] || ENV[env.upcase] or return
  require 'shellwords'
  parse(*Shellwords.shellwords(env))
end
getopts(*args) click to toggle source

Wrapper method for getopts.rb.

params = ARGV.getopts("ab:", "foo", "bar:")
# params[:a] = true   # -a
# params[:b] = "1"    # -b1
# params[:foo] = "1"  # --foo
# params[:bar] = "x"  # --bar x
# File lib/optparse.rb, line 1472
def getopts(*args)
  argv = Array === args.first ? args.shift : default_argv
  single_options, *long_options = *args

  result = {}

  single_options.scan(/(.)(:)?/) do |opt, val|
    if val
      result[opt] = nil
      define("-#{opt} VAL")
    else
      result[opt] = false
      define("-#{opt}")
    end
  end if single_options

  long_options.each do |arg|
    opt, val = arg.split(':', 2)
    if val
      result[opt] = val.empty? ? nil : val
      define("--#{opt} VAL")
    else
      result[opt] = false
      define("--#{opt}")
    end
  end

  parse_in_order(argv, result.method(:[]=))
  result
end
help() click to toggle source

Returns option summary string.

# File lib/optparse.rb, line 1071
def help; summarize("#{banner}".sub(/\n?\z/, "\n")) end
Also aliased as: to_s
inc(*args) click to toggle source
# File lib/optparse.rb, line 866
def inc(*args)
  self.class.inc(*args)
end
load(filename = nil) click to toggle source

Loads options from file names as filename. Does nothing when the file is not present. Returns whether successfully loaded.

filename defaults to basename of the program without suffix in a directory ~/.options.

# File lib/optparse.rb, line 1590
def load(filename = nil)
  begin
    filename ||= File.expand_path(File.basename($0, '.*'), '~/.options')
  rescue
    return false
  end
  begin
    parse(*IO.readlines(filename).each {|s| s.chomp!})
    true
  rescue Errno::ENOENT, Errno::ENOTDIR
    false
  end
end
make_switch(opts, block = nil) click to toggle source

Creates an OptionParser::Switch from the parameters. The parsed argument value is passed to the given block, where it can be processed.

See at the beginning of OptionParser for some full examples.

opts can include the following elements:

Argument style:

One of the following:

:NONE, :REQUIRED, :OPTIONAL
Argument pattern:

Acceptable option argument format, must be pre-defined with #accept or #accept, or Regexp. This can appear once or assigned as String if not present, otherwise causes an ArgumentError. Examples:

Float, Time, Array
Possible argument values:

Hash or Array.

[:text, :binary, :auto]
%w[iso-2022-jp shift_jis euc-jp utf8 binary]
{ "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
Long style switch:

Specifies a long style switch which takes a mandatory, optional or no argument. It's a string of the following form:

"--switch=MANDATORY" or "--switch MANDATORY"
"--switch[=OPTIONAL]"
"--switch"
Short style switch:

Specifies short style switch which takes a mandatory, optional or no argument. It's a string of the following form:

"-xMANDATORY"
"-x[OPTIONAL]"
"-x"

There is also a special form which matches character range (not full set of regular expression):

"-[a-z]MANDATORY"
"-[a-z][OPTIONAL]"
"-[a-z]"
Argument style and description:

Instead of specifying mandatory or optional arguments directly in the switch parameter, this separate parameter can be used.

"=MANDATORY"
"=[OPTIONAL]"
Description:

Description string for the option.

"Run verbosely"
Handler:

Handler for the parsed argument value. Either give a block or pass a Proc or Method as an argument.

# File lib/optparse.rb, line 1155
def make_switch(opts, block = nil)
  short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []
  ldesc, sdesc, desc, arg = [], [], []
  default_style = Switch::NoArgument
  default_pattern = nil
  klass = nil
  q, a = nil

  opts.each do |o|
    # argument class
    next if search(:atype, o) do |pat, c|
      klass = notwice(o, klass, 'type')
      if not_style and not_style != Switch::NoArgument
        not_pattern, not_conv = pat, c
      else
        default_pattern, conv = pat, c
      end
    end

    # directly specified pattern(any object possible to match)
    if (!(String === o || Symbol === o)) and o.respond_to?(:match)
      pattern = notwice(o, pattern, 'pattern')
      if pattern.respond_to?(:convert)
        conv = pattern.method(:convert).to_proc
      else
        conv = SPLAT_PROC
      end
      next
    end

    # anything others
    case o
    when Proc, Method
      block = notwice(o, block, 'block')
    when Array, Hash
      case pattern
      when CompletingHash
      when nil
        pattern = CompletingHash.new
        conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
      else
        raise ArgumentError, "argument pattern given twice"
      end
      o.each {|pat, *v| pattern[pat] = v.fetch(0) {pat}}
    when Module
      raise ArgumentError, "unsupported argument type: #{o}", ParseError.filter_backtrace(caller(4))
    when *ArgumentStyle.keys
      style = notwice(ArgumentStyle[o], style, 'style')
    when /^--no-([^\[\]=\s]*)(.+)?/
      q, a = $1, $2
      o = notwice(a ? Object : TrueClass, klass, 'type')
      not_pattern, not_conv = search(:atype, o) unless not_style
      not_style = (not_style || default_style).guess(arg = a) if a
      default_style = Switch::NoArgument
      default_pattern, conv = search(:atype, FalseClass) unless default_pattern
      ldesc << "--no-#{q}"
      long << 'no-' + (q = q.downcase)
      nolong << q
    when /^--\[no-\]([^\[\]=\s]*)(.+)?/
      q, a = $1, $2
      o = notwice(a ? Object : TrueClass, klass, 'type')
      if a
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      end
      ldesc << "--[no-]#{q}"
      long << (o = q.downcase)
      not_pattern, not_conv = search(:atype, FalseClass) unless not_style
      not_style = Switch::NoArgument
      nolong << 'no-' + o
    when /^--([^\[\]=\s]*)(.+)?/
      q, a = $1, $2
      if a
        o = notwice(NilClass, klass, 'type')
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      end
      ldesc << "--#{q}"
      long << (o = q.downcase)
    when /^-(\[\^?\]?(?:[^\\]]|\.)*\])(.+)?/
      q, a = $1, $2
      o = notwice(Object, klass, 'type')
      if a
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      end
      sdesc << "-#{q}"
      short << Regexp.new(q)
    when /^-(.)(.+)?/
      q, a = $1, $2
      if a
        o = notwice(NilClass, klass, 'type')
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      end
      sdesc << "-#{q}"
      short << q
    when /^=/
      style = notwice(default_style.guess(arg = o), style, 'style')
      default_pattern, conv = search(:atype, Object) unless default_pattern
    else
      desc.push(o)
    end
  end

  default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern
  if !(short.empty? and long.empty?)
    s = (style || default_style).new(pattern || default_pattern,
                                     conv, sdesc, ldesc, arg, desc, block)
  elsif !block
    if style or pattern
      raise ArgumentError, "no switch given", ParseError.filter_backtrace(caller)
    end
    s = desc
  else
    short << pattern
    s = (style || default_style).new(pattern,
                                     conv, nil, nil, arg, desc, block)
  end
  return s, short, long,
    (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),
    nolong
end
new() { |self| ... } click to toggle source

Pushes a new List.

# File lib/optparse.rb, line 1037
def new
  @stack.push(List.new)
  if block_given?
    yield self
  else
    self
  end
end
on(*opts, &block) click to toggle source

Add option switch and handler. See make_switch for an explanation of parameters.

# File lib/optparse.rb, line 1288
def on(*opts, &block)
  define(*opts, &block)
  self
end
on_head(*opts, &block) click to toggle source

Add option switch like with on, but at head of summary.

# File lib/optparse.rb, line 1302
def on_head(*opts, &block)
  define_head(*opts, &block)
  self
end
on_tail(*opts, &block) click to toggle source

Add option switch like with on, but at tail of summary.

# File lib/optparse.rb, line 1316
def on_tail(*opts, &block)
  define_tail(*opts, &block)
  self
end
order(*argv, &block) click to toggle source

Parses command line arguments argv in order. When a block is given, each non-option argument is yielded.

Returns the rest of argv left unparsed.

# File lib/optparse.rb, line 1335
def order(*argv, &block)
  argv = argv[0].dup if argv.size == 1 and Array === argv[0]
  order!(argv, &block)
end
order!(argv = default_argv, &nonopt) click to toggle source

Same as order, but removes switches destructively. Non-option arguments remain in argv.

# File lib/optparse.rb, line 1344
def order!(argv = default_argv, &nonopt)
  parse_in_order(argv, &nonopt)
end
parse(*argv) click to toggle source

Parses command line arguments argv in order when environment variable POSIXLY_CORRECT is set, and in permutation mode otherwise.

# File lib/optparse.rb, line 1446
def parse(*argv)
  argv = argv[0].dup if argv.size == 1 and Array === argv[0]
  parse!(argv)
end
parse!(argv = default_argv) click to toggle source

Same as parse, but removes switches destructively. Non-option arguments remain in argv.

# File lib/optparse.rb, line 1455
def parse!(argv = default_argv)
  if ENV.include?('POSIXLY_CORRECT')
    order!(argv)
  else
    permute!(argv)
  end
end
permute(*argv) click to toggle source

Parses command line arguments argv in permutation mode and returns list of non-option arguments.

# File lib/optparse.rb, line 1426
def permute(*argv)
  argv = argv[0].dup if argv.size == 1 and Array === argv[0]
  permute!(argv)
end
permute!(argv = default_argv) click to toggle source

Same as permute, but removes switches destructively. Non-option arguments remain in argv.

# File lib/optparse.rb, line 1435
def permute!(argv = default_argv)
  nonopts = []
  order!(argv, &nonopts.method(:<<))
  argv[0, 0] = nonopts
  argv
end
program_name() click to toggle source

Program name to be emitted in error message and default banner, defaults to $0.

# File lib/optparse.rb, line 972
def program_name
  @program_name || File.basename($0, '.*')
end
reject(*args, &blk) click to toggle source

Directs to reject specified class argument.

t

Argument class specifier, any object including Class.

reject(t)
# File lib/optparse.rb, line 931
def reject(*args, &blk) top.reject(*args, &blk) end
release() click to toggle source

Release code

# File lib/optparse.rb, line 997
def release
  @release || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)
end
remove() click to toggle source

Removes the last List.

# File lib/optparse.rb, line 1049
def remove
  @stack.pop
end
separator(string) click to toggle source

Add separator in summary.

# File lib/optparse.rb, line 1325
def separator(string)
  top.append(string, nil, nil)
end
summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk) click to toggle source

Puts option summary into to and returns to. Yields each line if a block is given.

to

Output destination, which must have method <<. Defaults to [].

width

Width of left side, defaults to @summary_width.

max

Maximum length allowed for left side, defaults to width - 1.

indent

Indentation, defaults to @summary_indent.

# File lib/optparse.rb, line 1062
def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk)
  blk ||= proc {|l| to << (l.index($/, -1) ? l : l + $/)}
  visit(:summarize, {}, {}, width, max, indent, &blk)
  to
end
terminate(arg = nil) click to toggle source

Terminates option parsing. Optional parameter arg is a string pushed back to be the first non-option argument.

# File lib/optparse.rb, line 899
def terminate(arg = nil)
  self.class.terminate(arg)
end
to_a() click to toggle source

Returns option summary list.

# File lib/optparse.rb, line 1077
def to_a; summarize("#{banner}".split(/^/)) end
to_s() click to toggle source
Alias for: help
top() click to toggle source

Subject of on / on_head, accept / reject

# File lib/optparse.rb, line 1023
def top
  @stack[-1]
end
ver() click to toggle source

Returns version string from #program_name, version and release.

# File lib/optparse.rb, line 1004
def ver
  if v = version
    str = "#{program_name} #{[v].join('.')}"
    str << " (#{v})" if v = release
    str
  end
end
version() click to toggle source

Version

# File lib/optparse.rb, line 990
def version
  @version || (defined?(::Version) && ::Version)
end
warn(mesg = $!) click to toggle source
# File lib/optparse.rb, line 1012
def warn(mesg = $!)
  super("#{program_name}: #{mesg}")
end


class OptionParser::AC - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::AC

In Files

  • lib/optparse/ac.rb

Parent

OptionParser

Public Instance Methods

ac_arg_disable(name, help_string, &block) click to toggle source
# File lib/optparse/ac.rb, line 34
def ac_arg_disable(name, help_string, &block)
  _ac_arg_enable("disable", name, help_string, block)
end
ac_arg_enable(name, help_string, &block) click to toggle source
# File lib/optparse/ac.rb, line 30
def ac_arg_enable(name, help_string, &block)
  _ac_arg_enable("enable", name, help_string, block)
end
ac_arg_with(name, help_string, &block) click to toggle source
# File lib/optparse/ac.rb, line 38
def ac_arg_with(name, help_string, &block)
  _check_ac_args(name, block)

  sdesc = []
  ldesc = ["--with-#{name}"]
  desc = [help_string]
  q = name.downcase
  with = Switch::PlacedArgument.new(*search(:atype, String), sdesc, ldesc, nil, desc, block)
  without = Switch::NoArgument.new(nil, proc {}, sdesc, ldesc, nil, desc, block)
  top.append(with, [], ["with-" + q], without, ['without-' + q])
  with
end


module OptionParser::Acceptables - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OptionParser::Acceptables

Acceptable argument classes. Now contains DecimalInteger, OctalInteger and DecimalNumeric. See Acceptable argument classes (in source code).

In Files

  • lib/optparse.rb


class OptionParser::AmbiguousArgument - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::AmbiguousArgument

Raises when the given argument word can't be completed uniquely.

In Files

  • lib/optparse.rb

Parent

OptionParser::InvalidArgument


class OptionParser::AmbiguousOption - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::AmbiguousOption

Raises when ambiguously completable string is encountered.

In Files

  • lib/optparse.rb

Parent

OptionParser::ParseError


module OptionParser::Arguable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OptionParser::Arguable

Extends command line arguments array (ARGV) to parse itself.

In Files

  • lib/optparse.rb

Public Class Methods

extend_object(obj) click to toggle source

Initializes instance variable.

# File lib/optparse.rb, line 1939
def self.extend_object(obj)
  super
  obj.instance_eval {@optparse = nil}
end
new(*args) click to toggle source
# File lib/optparse.rb, line 1943
def initialize(*args)
  super
  @optparse = nil
end

Public Instance Methods

getopts(*args) click to toggle source

Substitution of getopts is possible as follows. Also see OptionParser#getopts.

def getopts(*args)
  ($OPT = ARGV.getopts(*args)).each do |opt, val|
    eval "$OPT_#{opt.gsub(/[^A-Za-z0-9_]/, '_')} = val"
  end
rescue OptionParser::ParseError
end

# File lib/optparse.rb, line 1932
def getopts(*args)
  options.getopts(self, *args)
end
options() { |optparse| ... } click to toggle source

Actual OptionParser object, automatically created if nonexistent.

If called with a block, yields the OptionParser object and returns the result of the block. If an OptionParser::ParseError exception occurs in the block, it is rescued, a error message printed to STDERR and nil returned.

# File lib/optparse.rb, line 1891
def options
  @optparse ||= OptionParser.new
  @optparse.default_argv = self
  block_given? or return @optparse
  begin
    yield @optparse
  rescue ParseError
    @optparse.warn $!
    nil
  end
end
options=(opt) click to toggle source

Sets OptionParser object, when opt is false or nil, methods #options and #options= are undefined. Thus, there is no ways to access the OptionParser object via the receiver object.

# File lib/optparse.rb, line 1874
def options=(opt)
  unless @optparse = opt
    class << self
      undef_method(:options)
      undef_method(:options=)
    end
  end
end
order!(&blk) click to toggle source

Parses self destructively in order and returns self containing the rest arguments left unparsed.

# File lib/optparse.rb, line 1907
def order!(&blk) options.order!(self, &blk) end
parse!() click to toggle source

Parses self destructively and returns self containing the rest arguments left unparsed.

# File lib/optparse.rb, line 1919
def parse!() options.parse!(self) end
permute!() click to toggle source

Parses self destructively in permutation mode and returns self containing the rest arguments left unparsed.

# File lib/optparse.rb, line 1913
def permute!() options.permute!(self) end


class OptionParser::CompletingHash - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::CompletingHash

Hash with completion search feature. See OptionParser::Completion.

In Files

  • lib/optparse.rb

Parent

Hash

Included Modules

  • OptionParser::Completion

Public Instance Methods

match(key) click to toggle source

Completion for hash key.

# File lib/optparse.rb, line 722
def match(key)
  *values = fetch(key) {
    raise AmbiguousArgument, catch(:ambiguous) {return complete(key)}
  }
  return key, *values
end


module OptionParser::Completion - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module OptionParser::Completion

Keyword completion module. This allows partial arguments to be specified and resolved against a list of acceptable values.

In Files

  • lib/optparse.rb

Public Class Methods

candidate(key, icase = false, pat = nil, &block) click to toggle source
# File lib/optparse.rb, line 234
def self.candidate(key, icase = false, pat = nil, &block)
  pat ||= Completion.regexp(key, icase)
  candidates = []
  block.call do |k, *v|
    (if Regexp === k
       kn = nil
       k === key
     else
       kn = defined?(k.id2name) ? k.id2name : k
       pat === kn
     end) or next
    v << k if v.empty?
    candidates << [k, v, kn]
  end
  candidates
end
regexp(key, icase) click to toggle source
# File lib/optparse.rb, line 230
def self.regexp(key, icase)
  Regexp.new('\A' + Regexp.quote(key).gsub(/\w+\b/, '\&\w*'), icase)
end

Public Instance Methods

candidate(key, icase = false, pat = nil) click to toggle source
# File lib/optparse.rb, line 251
def candidate(key, icase = false, pat = nil)
  Completion.candidate(key, icase, pat, &method(:each))
end
complete(key, icase = false, pat = nil) { |key, *sw| ... } click to toggle source
# File lib/optparse.rb, line 256
def complete(key, icase = false, pat = nil)
  candidates = candidate(key, icase, pat, &method(:each)).sort_by {|k, v, kn| kn.size}
  if candidates.size == 1
    canon, sw, * = candidates[0]
  elsif candidates.size > 1
    canon, sw, cn = candidates.shift
    candidates.each do |k, v, kn|
      next if sw == v
      if String === cn and String === kn
        if cn.rindex(kn, 0)
          canon, sw, cn = k, v, kn
          next
        elsif kn.rindex(cn, 0)
          next
        end
      end
      throw :ambiguous, key
    end
  end
  if canon
    block_given? or return key, *sw
    yield(key, *sw)
  end
end
convert(opt = nil, val = nil, *) click to toggle source
# File lib/optparse.rb, line 281
def convert(opt = nil, val = nil, *)
  val
end


class OptionParser::InvalidArgument - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::InvalidArgument

Raises when the given argument does not match required format.

In Files

  • lib/optparse.rb

Parent

OptionParser::ParseError


class OptionParser::InvalidOption - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::InvalidOption

Raises when switch is undefined.

In Files

  • lib/optparse.rb

Parent

OptionParser::ParseError


class OptionParser::List - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::List

Simple option list providing mapping from short and/or long option string to OptionParser::Switch and mapping from acceptable argument to matching pattern and converter pair. Also provides summary feature.

In Files

  • lib/optparse.rb

Parent

Object

Attributes

atype[R]

Map from acceptable argument types to pattern and converter pairs.

list[R]

List of all switches and summary string.

long[R]

Map from long style option switches to actual switch objects.

short[R]

Map from short style option switches to actual switch objects.

Public Class Methods

new() click to toggle source

Just initializes all instance variables.

# File lib/optparse.rb, line 565
def initialize
  @atype = {}
  @short = OptionMap.new
  @long = OptionMap.new
  @list = []
end

Public Instance Methods

accept(t, pat = /.*/m, &block) click to toggle source

See OptionParser#accept.

# File lib/optparse.rb, line 575
def accept(t, pat = /.*/, &block)
  if pat
    pat.respond_to?(:match) or
      raise TypeError, "has no `match'", ParseError.filter_backtrace(caller(2))
  else
    pat = t if t.respond_to?(:match)
  end
  unless block
    block = pat.method(:convert).to_proc if pat.respond_to?(:convert)
  end
  @atype[t] = [pat, block]
end
append(*args) click to toggle source

Appends switch at the tail of the list, and associates short, long and negated long options. Arguments are:

switch

OptionParser::Switch instance to be inserted.

short_opts

List of short style options.

long_opts

List of long style options.

nolong_opts

List of long style options with “no-” prefix.

append(switch, short_opts, long_opts, nolong_opts)
# File lib/optparse.rb, line 639
def append(*args)
  update(*args)
  @list.push(args[0])
end
complete(id, opt, icase = false, *pat, &block) click to toggle source

Searches list id for opt and the optional patterns for completion pat. If icase is true, the search is case insensitive. The result is returned or yielded if a block is given. If it isn't found, nil is returned.

# File lib/optparse.rb, line 661
def complete(id, opt, icase = false, *pat, &block)
  __send__(id).complete(opt, icase, *pat, &block)
end
each_option(&block) click to toggle source

Iterates over each option, passing the option to the block.

# File lib/optparse.rb, line 668
def each_option(&block)
  list.each(&block)
end
prepend(*args) click to toggle source

Inserts switch at the head of the list, and associates short, long and negated long options. Arguments are:

switch

OptionParser::Switch instance to be inserted.

short_opts

List of short style options.

long_opts

List of long style options.

nolong_opts

List of long style options with “no-” prefix.

prepend(switch, short_opts, long_opts, nolong_opts)
# File lib/optparse.rb, line 623
def prepend(*args)
  update(*args)
  @list.unshift(args[0])
end
reject(t) click to toggle source

See OptionParser#reject.

# File lib/optparse.rb, line 591
def reject(t)
  @atype.delete(t)
end
search(id, key) { |val| ... } click to toggle source

Searches key in id list. The result is returned or yielded if a block is given. If it isn't found, nil is returned.

# File lib/optparse.rb, line 648
def search(id, key)
  if list = __send__(id)
    val = list.fetch(key) {return nil}
    block_given? ? yield(val) : val
  end
end
summarize(*args, &block) click to toggle source

Creates the summary table, passing each line to the block (without newline). The arguments args are passed along to the summarize method which is called on every option.

# File lib/optparse.rb, line 677
def summarize(*args, &block)
  sum = []
  list.reverse_each do |opt|
    if opt.respond_to?(:summarize) # perhaps OptionParser::Switch
      s = []
      opt.summarize(*args) {|l| s << l}
      sum.concat(s.reverse)
    elsif !opt or opt.empty?
      sum << ""
    elsif opt.respond_to?(:each_line)
      sum.concat([*opt.each_line].reverse)
    else
      sum.concat([*opt.each].reverse)
    end
  end
  sum.reverse_each(&block)
end


class OptionParser::MissingArgument - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::MissingArgument

Raises when a switch with mandatory argument has no argument.

In Files

  • lib/optparse.rb

Parent

OptionParser::ParseError


class OptionParser::NeedlessArgument - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::NeedlessArgument

Raises when there is an argument for a switch which takes no argument.

In Files

  • lib/optparse.rb

Parent

OptionParser::ParseError


class OptionParser::OptionMap - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::OptionMap

Map from option/keyword string to object with completion.

In Files

  • lib/optparse.rb

Parent

Hash

Included Modules

  • OptionParser::Completion


class OptionParser::ParseError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::ParseError

Base class of exceptions from OptionParser.

In Files

  • lib/optparse.rb

Parent

RuntimeError

Constants

Reason

Reason which caused the error.

Attributes

args[R]
reason[W]

Public Class Methods

filter_backtrace(array) click to toggle source
# File lib/optparse.rb, line 1776
def self.filter_backtrace(array)
  unless $DEBUG
    array.delete_if(&%r\A#{Regexp.quote(__FILE__)}:".method(:=~))
  end
  array
end
new(*args) click to toggle source
# File lib/optparse.rb, line 1760
def initialize(*args)
  @args = args
  @reason = nil
end

Public Instance Methods

inspect() click to toggle source
# File lib/optparse.rb, line 1803
def inspect
  "#<#{self.class.to_s}: #{args.join(' ')}>"
end
message() click to toggle source

Default stringizing method to emit standard error message.

# File lib/optparse.rb, line 1810
def message
  reason + ': ' + args.join(' ')
end
Also aliased as: to_s
reason() click to toggle source

Returns error reason. Override this for I18N.

# File lib/optparse.rb, line 1799
def reason
  @reason || self.class::Reason
end
recover(argv) click to toggle source

Pushes back erred argument(s) to argv.

# File lib/optparse.rb, line 1771
def recover(argv)
  argv[0, 0] = @args
  argv
end
set_backtrace(array) click to toggle source
# File lib/optparse.rb, line 1783
def set_backtrace(array)
  super(self.class.filter_backtrace(array))
end
set_option(opt, eq) click to toggle source
# File lib/optparse.rb, line 1787
def set_option(opt, eq)
  if eq
    @args[0] = opt
  else
    @args.unshift(opt)
  end
  self
end
to_s() click to toggle source
Alias for: message


class OptionParser::Switch - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::Switch

Individual switch class. Not important to the user.

Defined within Switch are several Switch-derived classes: NoArgument, RequiredArgument, etc.

In Files

  • lib/optparse.rb

Parent

Object

Attributes

arg[R]
block[R]
conv[R]
desc[R]
long[R]
pattern[R]
short[R]

Public Class Methods

guess(arg) click to toggle source

Guesses argument style from arg. Returns corresponding OptionParser::Switch class (OptionalArgument, etc.).

# File lib/optparse.rb, line 308
def self.guess(arg)
  case arg
  when ""
    t = self
  when /\A=?\[/
    t = Switch::OptionalArgument
  when /\A\s+\[/
    t = Switch::PlacedArgument
  else
    t = Switch::RequiredArgument
  end
  self >= t or incompatible_argument_styles(arg, t)
  t
end
incompatible_argument_styles(arg, t) click to toggle source
# File lib/optparse.rb, line 323
def self.incompatible_argument_styles(arg, t)
  raise(ArgumentError, "#{arg}: incompatible argument styles\n  #{self}, #{t}",
        ParseError.filter_backtrace(caller(2)))
end
new(pattern = nil, conv = nil, short = nil, long = nil, arg = nil, desc = ([] if short or long), block = Proc.new) click to toggle source
# File lib/optparse.rb, line 332
def initialize(pattern = nil, conv = nil,
               short = nil, long = nil, arg = nil,
               desc = ([] if short or long), block = Proc.new)
  raise if Array === pattern
  @pattern, @conv, @short, @long, @arg, @desc, @block =
    pattern, conv, short, long, arg, desc, block
end
pattern() click to toggle source
# File lib/optparse.rb, line 328
def self.pattern
  NilClass
end

Public Instance Methods

summarize(sdone = [], ldone = [], width = 1, max = width - 1, indent = "") { |indent| ... } click to toggle source

Produces the summary text. Each line of the summary is yielded to the block (without newline).

sdone

Already summarized short style options keyed hash.

ldone

Already summarized long style options keyed hash.

width

Width of left side (option part). In other words, the right side (description part) starts after width columns.

max

Maximum width of left side -> the options are filled within max columns.

indent

Prefix string indents all summarized lines.

# File lib/optparse.rb, line 391
def summarize(sdone = [], ldone = [], width = 1, max = width - 1, indent = "")
  sopts, lopts = [], [], nil
  @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
  @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
  return if sopts.empty? and lopts.empty? # completely hidden

  left = [sopts.join(', ')]
  right = desc.dup

  while s = lopts.shift
    l = left[-1].length + s.length
    l += arg.length if left.size == 1 && arg
    l < max or sopts.empty? or left << ''
    left[-1] << if left[-1].empty? then ' ' * 4 else ', ' end << s
  end

  if arg
    left[0] << (left[1] ? arg.sub(/\A(\[?)=/, '\1') + ',' : arg)
  end
  mlen = left.collect {|ss| ss.length}.max.to_i
  while mlen > width and l = left.shift
    mlen = left.collect {|ss| ss.length}.max.to_i if l.length == mlen
    if l.length < width and (r = right[0]) and !r.empty?
      l = l.to_s.ljust(width) + ' ' + r
      right.shift
    end
    yield(indent + l)
  end

  while begin l = left.shift; r = right.shift; l or r end
    l = l.to_s.ljust(width) + ' ' + r if r and !r.empty?
    yield(indent + l)
  end

  self
end
switch_name() click to toggle source

Main name of the switch.

# File lib/optparse.rb, line 443
def switch_name
  (long.first || short.first).sub(/\A-+(?:\[no-\])?/, '')
end


class OptionParser::Switch::NoArgument - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::Switch::NoArgument

Switch that takes no arguments.

In Files

  • lib/optparse.rb

Parent

self

Public Class Methods

incompatible_argument_styles(*) click to toggle source
# File lib/optparse.rb, line 478
def self.incompatible_argument_styles(*)
end
pattern() click to toggle source
# File lib/optparse.rb, line 481
def self.pattern
  Object
end

Public Instance Methods

parse(arg, argv) { |NeedlessArgument, arg| ... } click to toggle source

Raises an exception if any arguments given.

# File lib/optparse.rb, line 473
def parse(arg, argv)
  yield(NeedlessArgument, arg) if arg
  conv_arg(arg)
end


class OptionParser::Switch::OptionalArgument - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::Switch::OptionalArgument

Switch that can omit argument.

In Files

  • lib/optparse.rb

Parent

self

Public Instance Methods

parse(arg, argv, &error) click to toggle source

Parses argument if given, or uses default value.

# File lib/optparse.rb, line 511
def parse(arg, argv, &error)
  if arg
    conv_arg(*parse_arg(arg, &error))
  else
    conv_arg(arg)
  end
end


class OptionParser::Switch::PlacedArgument - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::Switch::PlacedArgument

Switch that takes an argument, which does not begin with '-'.

In Files

  • lib/optparse.rb

Parent

self

Public Instance Methods

parse(arg, argv, &error) click to toggle source

Returns nil if argument is not present or begins with '-'.

# File lib/optparse.rb, line 528
def parse(arg, argv, &error)
  if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
    return nil, block, nil
  end
  opt = (val = parse_arg(val, &error))[1]
  val = conv_arg(*val)
  if opt and !arg
    argv.shift
  else
    val[0] = nil
  end
  val
end


class OptionParser::Switch::RequiredArgument - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class OptionParser::Switch::RequiredArgument

Switch that takes an argument.

In Files

  • lib/optparse.rb

Parent

self

Public Instance Methods

parse(arg, argv) click to toggle source

Raises an exception if argument is not present.

# File lib/optparse.rb, line 494
def parse(arg, argv)
  unless arg
    raise MissingArgument if argv.empty?
    arg = argv.shift
  end
  conv_arg(*parse_arg(arg, &method(:raise)))
end


class PP - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PP

Pretty-printer for Ruby objects.

Which seems better?

non-pretty-printed output by p is:

#<PP:0x81fedf0 @genspace=#<Proc:0x81feda0>, @group_queue=#<PrettyPrint::GroupQueue:0x81fed3c @queue=[[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], []]>, @buffer=[], @newline="\n", @group_stack=[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], @buffer_width=0, @indent=0, @maxwidth=79, @output_width=2, @output=#<IO:0x8114ee4>>

pretty-printed output by pp is:

#<PP:0x81fedf0
 @buffer=[],
 @buffer_width=0,
 @genspace=#<Proc:0x81feda0>,
 @group_queue=
  #<PrettyPrint::GroupQueue:0x81fed3c
   @queue=
    [[#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
     []]>,
 @group_stack=
  [#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
 @indent=0,
 @maxwidth=79,
 @newline="\n",
 @output=#<IO:0x8114ee4>,
 @output_width=2>

I like the latter. If you do too, this library is for you.

Usage

pp(obj)             #=> obj
pp(obj1, obj2, ...) #=> [obj1, obj2, ...]
pp()                #=> nil

output +obj(s)+ to +$>+ in pretty printed format.

It returns +obj(s)+.

Output Customization

To define your customized pretty printing function for your classes, redefine a method pretty_print(pp) in the class. It takes an argument pp which is an instance of the class PP. The method should use PrettyPrint#text, PrettyPrint#breakable, PrettyPrint#nest, PrettyPrint#group and PP::PPMethods#pp to print the object.

Author

Tanaka Akira <akr@m17n.org>

In Files

  • lib/pp.rb

Parent

PrettyPrint

Included Modules

  • PP::PPMethods

Attributes

sharing_detection[RW]

Returns the sharing detection flag as a boolean value. It is false by default.

Public Class Methods

pp(obj, out=$>, width=79) click to toggle source

Outputs obj to out in pretty printed format of width columns in width.

If out is omitted, +$>+ is assumed. If width is omitted, 79 is assumed.

::pp returns out.

# File lib/pp.rb, line 76
def PP.pp(obj, out=$>, width=79)
  q = PP.new(out, width)
  q.guard_inspect_key {q.pp obj}
  q.flush
  #$pp = q
  out << "\n"
end
singleline_pp(obj, out=$>) click to toggle source

Outputs obj to out like ::pp but with no indent and newline.

::singleline_pp returns out.

# File lib/pp.rb, line 88
def PP.singleline_pp(obj, out=$>)
  q = SingleLine.new(out)
  q.guard_inspect_key {q.pp obj}
  q.flush
  out
end


module PP::ObjectMixin - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module PP::ObjectMixin

In Files

  • lib/pp.rb

Public Instance Methods

pretty_print(q) click to toggle source

A default pretty printing method for general objects. It calls pretty_print_instance_variables to list instance variables.

If self has a customized (redefined) inspect method, the result of self.inspect is used but it obviously has no line break hints.

This module provides predefined pretty_print methods for some of the most commonly used built-in classes for convenience.

# File lib/pp.rb, line 279
def pretty_print(q)
  method_method = Object.instance_method(:method).bind(self)
  begin
    inspect_method = method_method.call(:inspect)
  rescue NameError
  end
  if inspect_method && /\(Kernel\)#/ !~ inspect_method.inspect
    q.text self.inspect
  elsif !inspect_method && self.respond_to?(:inspect)
    q.text self.inspect
  else
    q.pp_object(self)
  end
end
pretty_print_cycle(q) click to toggle source

A default pretty printing method for general objects that are detected as part of a cycle.

# File lib/pp.rb, line 296
def pretty_print_cycle(q)
  q.object_address_group(self) {
    q.breakable
    q.text '...'
  }
end
pretty_print_inspect() click to toggle source

Is inspect implementation using pretty_print. If you implement pretty_print, it can be used as follows.

alias inspect pretty_print_inspect

However, doing this requires that every class that inspect is called on implement pretty_print, or a RuntimeError will be raised.

# File lib/pp.rb, line 318
def pretty_print_inspect
  if /\(PP::ObjectMixin\)#/ =~ Object.instance_method(:method).bind(self).call(:pretty_print).inspect
    raise "pretty_print is not overridden for #{self.class}"
  end
  PP.singleline_pp(self, '')
end
pretty_print_instance_variables() click to toggle source

Returns a sorted array of instance variable names.

This method should return an array of names of instance variables as symbols or strings as: +[:@a, :@b]+.

# File lib/pp.rb, line 307
def pretty_print_instance_variables
  instance_variables.sort
end


module PP::PPMethods - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module PP::PPMethods

In Files

  • lib/pp.rb

Constants

PointerFormat
PointerMask

Public Instance Methods

check_inspect_key(id) click to toggle source
# File lib/pp.rb, line 128
def check_inspect_key(id)
  Thread.current[:__recursive_key__] &&
  Thread.current[:__recursive_key__][:inspect] &&
  Thread.current[:__recursive_key__][:inspect].include?(id)
end
comma_breakable() click to toggle source

A convenience method which is same as follows:

text ','
breakable
# File lib/pp.rb, line 186
def comma_breakable
  text ','
  breakable
end
guard_inspect_key() { || ... } click to toggle source
# File lib/pp.rb, line 109
def guard_inspect_key
  if Thread.current[:__recursive_key__] == nil
    Thread.current[:__recursive_key__] = {}.untrust
  end

  if Thread.current[:__recursive_key__][:inspect] == nil
    Thread.current[:__recursive_key__][:inspect] = {}.untrust
  end

  save = Thread.current[:__recursive_key__][:inspect]

  begin
    Thread.current[:__recursive_key__][:inspect] = {}.untrust
    yield
  ensure
    Thread.current[:__recursive_key__][:inspect] = save
  end
end
object_address_group(obj, &block) click to toggle source
# File lib/pp.rb, line 177
def object_address_group(obj, &block)
  id = PointerFormat % (obj.object_id * 2 & PointerMask)
  group(1, "\#<#{obj.class}:0x#{id}", '>', &block)
end
object_group(obj) { || ... } click to toggle source

A convenience method which is same as follows:

group(1, '#<' + obj.class.name, '>') { ... }

# File lib/pp.rb, line 164
def object_group(obj, &block) # :yield:
  group(1, '#<' + obj.class.name, '>', &block)
end
pop_inspect_key(id) click to toggle source
# File lib/pp.rb, line 136
def pop_inspect_key(id)
  Thread.current[:__recursive_key__][:inspect].delete id
end
pp(obj) click to toggle source

Adds obj to the pretty printing buffer using Object#pretty_print or Object#pretty_print_cycle.

Object#pretty_print_cycle is used when obj is already printed, a.k.a the object reference chain has a cycle.

# File lib/pp.rb, line 145
def pp(obj)
  id = obj.object_id

  if check_inspect_key(id)
    group {obj.pretty_print_cycle self}
    return
  end

  begin
    push_inspect_key(id)
    group {obj.pretty_print self}
  ensure
    pop_inspect_key(id) unless PP.sharing_detection
  end
end
pp_hash(obj) click to toggle source
# File lib/pp.rb, line 243
def pp_hash(obj)
  group(1, '{', '}') {
    seplist(obj, nil, :each_pair) {|k, v|
      group {
        pp k
        text '=>'
        group(1) {
          breakable ''
          pp v
        }
      }
    }
  }
end
pp_object(obj) click to toggle source
# File lib/pp.rb, line 228
def pp_object(obj)
  object_address_group(obj) {
    seplist(obj.pretty_print_instance_variables, lambda { text ',' }) {|v|
      breakable
      v = v.to_s if Symbol === v
      text v
      text '='
      group(1) {
        breakable ''
        pp(obj.instance_eval(v))
      }
    }
  }
end
push_inspect_key(id) click to toggle source
# File lib/pp.rb, line 133
def push_inspect_key(id)
  Thread.current[:__recursive_key__][:inspect][id] = true
end
seplist(list, sep=nil, iter_method=:each) { |element| ... } click to toggle source

Adds a separated list. The list is separated by comma with breakable space, by default.

seplist iterates the list using iter_method. It yields each object to the block given for seplist. The procedure separator_proc is called between each yields.

If the iteration is zero times, separator_proc is not called at all.

If separator_proc is nil or not given, +lambda { #comma_breakable }+ is used. If iter_method is not given, :each is used.

For example, following 3 code fragments has similar effect.

q.seplist([1,2,3]) {|v| xxx v }

q.seplist([1,2,3], lambda { q.comma_breakable }, :each) {|v| xxx v }

xxx 1
q.comma_breakable
xxx 2
q.comma_breakable
xxx 3

# File lib/pp.rb, line 215
def seplist(list, sep=nil, iter_method=:each) # :yield: element
  sep ||= lambda { comma_breakable }
  first = true
  list.__send__(iter_method) {|*v|
    if first
      first = false
    else
      sep.call
    end
    yield(*v)
  }
end


class PP::SingleLine - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PP::SingleLine

In Files

  • lib/pp.rb

Parent

PrettyPrint::SingleLine

Included Modules

  • PP::PPMethods


class PStore - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PStore

PStore implements a file based persistence mechanism based on a Hash. User code can store hierarchies of Ruby objects (values) into the data store file by name (keys). An object hierarchy may be just a single object. User code may later read values back from the data store or even update data, as needed.

The transactional behavior ensures that any changes succeed or fail together. This can be used to ensure that the data store is not left in a transitory state, where some values were updated but others were not.

Behind the scenes, Ruby objects are stored to the data store file with Marshal. That carries the usual limitations. Proc objects cannot be marshalled, for example.

Usage example:

require "pstore"

# a mock wiki object...
class WikiPage
  def initialize( page_name, author, contents )
    @page_name = page_name
    @revisions = Array.new

    add_revision(author, contents)
  end

  attr_reader :page_name

  def add_revision( author, contents )
    @revisions << { :created  => Time.now,
                    :author   => author,
                    :contents => contents }
  end

  def wiki_page_references
    [@page_name] + @revisions.last[:contents].scan(/\b(?:[A-Z]+[a-z]+){2,}/)
  end

  # ...
end

# create a new page...
home_page = WikiPage.new( "HomePage", "James Edward Gray II",
                          "A page about the JoysOfDocumentation..." )

# then we want to update page data and the index together, or not at all...
wiki = PStore.new("wiki_pages.pstore")
wiki.transaction do  # begin transaction; do all of this or none of it
  # store page...
  wiki[home_page.page_name] = home_page
  # ensure that an index has been created...
  wiki[:wiki_index] ||= Array.new
  # update wiki index...
  wiki[:wiki_index].push(*home_page.wiki_page_references)
end                   # commit changes to wiki data store file

### Some time later... ###

# read wiki data...
wiki.transaction(true) do  # begin read-only transaction, no changes allowed
  wiki.roots.each do |data_root_name|
    p data_root_name
    p wiki[data_root_name]
  end
end

Transaction modes

By default, file integrity is only ensured as long as the operating system (and the underlying hardware) doesn't raise any unexpected I/O errors. If an I/O error occurs while PStore is writing to its file, then the file will become corrupted.

You can prevent this by setting pstore.ultra_safe = true. However, this results in a minor performance loss, and only works on platforms that support atomic file renames. Please consult the documentation for ultra_safe for details.

Needless to say, if you're storing valuable data with PStore, then you should backup the PStore files from time to time.

In Files

  • lib/pstore.rb

Parent

Object

Constants

EMPTY_MARSHAL_CHECKSUM
EMPTY_MARSHAL_DATA
EMPTY_STRING

Constant for relieving Ruby's garbage collector.

RDWR_ACCESS
RD_ACCESS
WR_ACCESS

Attributes

ultra_safe[RW]

Whether PStore should do its best to prevent file corruptions, even when under unlikely-to-occur error conditions such as out-of-space conditions and other unusual OS filesystem errors. Setting this flag comes at the price in the form of a performance loss.

This flag only has effect on platforms on which file renames are atomic (e.g. all POSIX platforms: Linux, MacOS X, FreeBSD, etc). The default value is false.

Public Class Methods

new(file, thread_safe = false) click to toggle source

To construct a PStore object, pass in the file path where you would like the data to be stored.

PStore objects are always reentrant. But if thread_safe is set to true, then it will become thread-safe at the cost of a minor performance hit.

# File lib/pstore.rb, line 118
def initialize(file, thread_safe = false)
  dir = File::dirname(file)
  unless File::directory? dir
    raise PStore::Error, format("directory %s does not exist", dir)
  end
  if File::exist? file and not File::readable? file
    raise PStore::Error, format("file %s not readable", file)
  end
  @filename = file
  @abort = false
  @ultra_safe = false
  @thread_safe = thread_safe
  @lock = Mutex.new
end

Public Instance Methods

[](name) click to toggle source

Retrieves a value from the PStore file data, by name. The hierarchy of Ruby objects stored under that root name will be returned.

WARNING: This method is only valid in a #transaction. It will raise PStore::Error if called at any other time.

# File lib/pstore.rb, line 154
def [](name)
  in_transaction
  @table[name]
end
[]=(name, value) click to toggle source

Stores an individual Ruby object or a hierarchy of Ruby objects in the data store file under the root name. Assigning to a name already in the data store clobbers the old data.

Example:

require "pstore"

store = PStore.new("data_file.pstore")
store.transaction do  # begin transaction
  # load some data into the store...
  store[:single_object] = "My data..."
  store[:obj_heirarchy] = { "Kev Jackson" => ["rational.rb", "pstore.rb"],
                            "James Gray"  => ["erb.rb", "pstore.rb"] }
end                   # commit changes to data store file

WARNING: This method is only valid in a #transaction and it cannot be read-only. It will raise PStore::Error if called at any other time.

# File lib/pstore.rb, line 199
def []=(name, value)
  in_transaction_wr
  @table[name] = value
end
abort() click to toggle source

Ends the current #transaction, discarding any changes to the data store.

Example:

require "pstore"

store = PStore.new("data_file.pstore")
store.transaction do  # begin transaction
  store[:one] = 1     # this change is not applied, see below...
  store[:two] = 2     # this change is not applied, see below...

  store.abort         # end transaction here, discard all changes

  store[:three] = 3   # this change is never reached
end

WARNING: This method is only valid in a #transaction. It will raise PStore::Error if called at any other time.

# File lib/pstore.rb, line 287
def abort
  in_transaction
  @abort = true
  throw :pstore_abort_transaction
end
commit() click to toggle source

Ends the current #transaction, committing any changes to the data store immediately.

Example:

require "pstore"

store = PStore.new("data_file.pstore")
store.transaction do  # begin transaction
  # load some data into the store...
  store[:one] = 1
  store[:two] = 2

  store.commit        # end transaction here, committing changes

  store[:three] = 3   # this change is never reached
end

WARNING: This method is only valid in a #transaction. It will raise PStore::Error if called at any other time.

# File lib/pstore.rb, line 261
def commit
  in_transaction
  @abort = false
  throw :pstore_abort_transaction
end
delete(name) click to toggle source

Removes an object hierarchy from the data store, by name.

WARNING: This method is only valid in a #transaction and it cannot be read-only. It will raise PStore::Error if called at any other time.

# File lib/pstore.rb, line 209
def delete(name)
  in_transaction_wr
  @table.delete name
end
fetch(name, default=PStore::Error) click to toggle source

This method is just like PStore#[], save that you may also provide a default value for the object. In the event the specified name is not found in the data store, your default will be returned instead. If you do not specify a default, PStore::Error will be raised if the object is not found.

WARNING: This method is only valid in a #transaction. It will raise PStore::Error if called at any other time.

# File lib/pstore.rb, line 168
def fetch(name, default=PStore::Error)
  in_transaction
  unless @table.key? name
    if default == PStore::Error
      raise PStore::Error, format("undefined root name `%s'", name)
    else
      return default
    end
  end
  @table[name]
end
path() click to toggle source

Returns the path to the data store file.

# File lib/pstore.rb, line 235
def path
  @filename
end
root?(name) click to toggle source

Returns true if the supplied name is currently in the data store.

WARNING: This method is only valid in a #transaction. It will raise PStore::Error if called at any other time.

# File lib/pstore.rb, line 230
def root?(name)
  in_transaction
  @table.key? name
end
roots() click to toggle source

Returns the names of all object hierarchies currently in the store.

WARNING: This method is only valid in a #transaction. It will raise PStore::Error if called at any other time.

# File lib/pstore.rb, line 220
def roots
  in_transaction
  @table.keys
end
transaction(read_only = false) { |pstore| ... } click to toggle source

Opens a new transaction for the data store. Code executed inside a block passed to this method may read and write data to and from the data store file.

At the end of the block, changes are committed to the data store automatically. You may exit the transaction early with a call to either #commit or #abort. See those methods for details about how changes are handled. Raising an uncaught Exception in the block is equivalent to calling #abort.

If read_only is set to true, you will only be allowed to read from the data store during the transaction and any attempts to change the data will raise a PStore::Error.

Note that PStore does not support nested transactions.

# File lib/pstore.rb, line 310
def transaction(read_only = false)  # :yields:  pstore
  value = nil
  if !@thread_safe
    raise PStore::Error, "nested transaction" unless @lock.try_lock
  else
    begin
      @lock.lock
    rescue ThreadError
      raise PStore::Error, "nested transaction"
    end
  end
  begin
    @rdonly = read_only
    @abort = false
    file = open_and_lock_file(@filename, read_only)
    if file
      begin
        @table, checksum, original_data_size = load_data(file, read_only)

        catch(:pstore_abort_transaction) do
          value = yield(self)
        end

        if !@abort && !read_only
          save_data(checksum, original_data_size, file)
        end
      ensure
        file.close if !file.closed?
      end
    else
      # This can only occur if read_only == true.
      @table = {}
      catch(:pstore_abort_transaction) do
        value = yield(self)
      end
    end
  ensure
    @lock.unlock
  end
  value
end


class PStore::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PStore::Error

The error type thrown by all PStore methods.

In Files

  • lib/pstore.rb

Parent

StandardError


module PTY - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module PTY

Creates and managed pseudo terminals (PTYs). See also en.wikipedia.org/wiki/Pseudo_terminal

PTY allows you to allocate new terminals using ::open or ::spawn a new terminal with a specific command.

Example

In this example we will change the buffering type in the factor command, assuming that factor uses stdio for stdout buffering.

If IO.pipe is used instead of ::open, this code deadlocks because factor's stdout is fully buffered.

# start by requiring the standard library PTY
require 'pty'

master, slave = PTY.open
read, write = IO.pipe
pid = spawn("factor", :in=>read, :out=>slave)
read.close     # we dont need the read
slave.close    # or the slave

# pipe "42" to the factor command
write.puts "42"
# output the response from factor
p master.gets #=> "42: 2 3 7\n"

# pipe "144" to factor and print out the response
write.puts "144"
p master.gets #=> "144: 2 2 2 2 3 3\n"
write.close # close the pipe

# The result of read operation when pty slave is closed is platform
# dependent.
ret = begin
        m.gets          # FreeBSD returns nil.
      rescue Errno::EIO # GNU/Linux raises EIO.
        nil
      end
p ret #=> nil

License

C) Copyright 1998 by Akinori Ito.

This software may be redistributed freely for this purpose, in full
or in part, provided that this entire copyright notice is included
on any copies of this software and applications and derivations thereof.

This software is provided on an "as is" basis, without warranty of any
kind, either expressed or implied, as to any matter including, but not
limited to warranty of fitness of purpose, or merchantability, or
results obtained from use of this software.

In Files

  • ext/pty/pty.c

Public Class Methods

check(pid, raise = false) → Process::Status or nil click to toggle source
check(pid, true) → nil or raises PTY::ChildExited

Checks the status of the child process specified by pid. Returns nil if the process is still alive.

If the process is not alive, and raise was true, a PTY::ChildExited exception will be raised. Otherwise it will return a Process::Status instance.

pid

The process id of the process to check

raise

If true and the process identified by pid is no longer alive a PTY::ChildExited is raised.

static VALUE
pty_check(int argc, VALUE *argv, VALUE self)
{
    VALUE pid, exc;
    pid_t cpid;
    int status;

    rb_scan_args(argc, argv, "11", &pid, &exc);
    cpid = rb_waitpid(NUM2PIDT(pid), &status, WNOHANG|WUNTRACED);
    if (cpid == -1 || cpid == 0) return Qnil;

    if (!RTEST(exc)) return rb_last_status_get();
    raise_from_check(cpid, status);

    UNREACHABLE;
}
spawn(command_line) { |r, w, pid| ... } click to toggle source
spawn(command_line) → [r, w, pid]
spawn(command, arguments, ...) { |r, w, pid| ... }
spawn(command, arguments, ...) → [r, w, pid]

Spawns the specified command on a newly allocated pty. You can also use the alias ::getpty.

The command's controlling tty is set to the slave device of the pty and its standard input/output/error is redirected to the slave device.

command and command_line are the full commands to run, given a String. Any additional arguments will be passed to the command.

Return values

In the non-block form this returns an array of size three, [r, w, pid].

In the block form these same values will be yielded to the block:

r

A readable IO that that contains the command's standard output and standard error

w

A writable IO that is the command's standard input

pid

The process identifier for the command.

static VALUE
pty_getpty(int argc, VALUE *argv, VALUE self)
{
    VALUE res;
    struct pty_info info;
    rb_io_t *wfptr,*rfptr;
    VALUE rport = rb_obj_alloc(rb_cFile);
    VALUE wport = rb_obj_alloc(rb_cFile);
    char SlaveName[DEVICELEN];

    MakeOpenFile(rport, rfptr);
    MakeOpenFile(wport, wfptr);

    establishShell(argc, argv, &info, SlaveName);

    rfptr->mode = rb_io_mode_flags("r");
    rfptr->fd = info.fd;
    rfptr->pathv = rb_obj_freeze(rb_str_new_cstr(SlaveName));

    wfptr->mode = rb_io_mode_flags("w") | FMODE_SYNC;
    wfptr->fd = rb_cloexec_dup(info.fd);
    if (wfptr->fd == -1)
        rb_sys_fail("dup()");
    rb_update_max_fd(wfptr->fd);
    wfptr->pathv = rfptr->pathv;

    res = rb_ary_new2(3);
    rb_ary_store(res,0,(VALUE)rport);
    rb_ary_store(res,1,(VALUE)wport);
    rb_ary_store(res,2,PIDT2NUM(info.child_pid));

    if (rb_block_given_p()) {
        rb_ensure(rb_yield, res, pty_detach_process, (VALUE)&info);
        return Qnil;
    }
    return res;
}
open → [master_io, slave_file] click to toggle source
open {|master_io, slave_file| ... } → block value

Allocates a pty (pseudo-terminal).

In the block form, yields two arguments master_io, slave_file and the value of the block is returned from open.

The IO and File are both closed after the block completes if they haven't been already closed.

PTY.open {|master, slave|
  p master      #=> #<IO:masterpty:/dev/pts/1>
  p slave      #=> #<File:/dev/pts/1>
  p slave.path #=> "/dev/pts/1"
}

In the non-block form, returns a two element array, [master_io, slave_file].

master, slave = PTY.open
# do something with master for IO, or the slave file

The arguments in both forms are:

master_io

the master of the pty, as an IO.

slave_file

the slave of the pty, as a File. The path to the terminal device is available via slave_file.path

static VALUE
pty_open(VALUE klass)
{
    int master_fd, slave_fd;
    char slavename[DEVICELEN];
    VALUE master_io, slave_file;
    rb_io_t *master_fptr, *slave_fptr;
    VALUE assoc;

    getDevice(&master_fd, &slave_fd, slavename, 1);

    master_io = rb_obj_alloc(rb_cIO);
    MakeOpenFile(master_io, master_fptr);
    master_fptr->mode = FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX;
    master_fptr->fd = master_fd;
    master_fptr->pathv = rb_obj_freeze(rb_sprintf("masterpty:%s", slavename));

    slave_file = rb_obj_alloc(rb_cFile);
    MakeOpenFile(slave_file, slave_fptr);
    slave_fptr->mode = FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX | FMODE_TTY;
    slave_fptr->fd = slave_fd;
    slave_fptr->pathv = rb_obj_freeze(rb_str_new_cstr(slavename));

    assoc = rb_assoc_new(master_io, slave_file);
    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, assoc, pty_close_pty, assoc);
    }
    return assoc;
}
spawn(command_line) { |r, w, pid| ... } click to toggle source
spawn(command_line) → [r, w, pid]
spawn(command, arguments, ...) { |r, w, pid| ... }
spawn(command, arguments, ...) → [r, w, pid]

Spawns the specified command on a newly allocated pty. You can also use the alias ::getpty.

The command's controlling tty is set to the slave device of the pty and its standard input/output/error is redirected to the slave device.

command and command_line are the full commands to run, given a String. Any additional arguments will be passed to the command.

Return values

In the non-block form this returns an array of size three, [r, w, pid].

In the block form these same values will be yielded to the block:

r

A readable IO that that contains the command's standard output and standard error

w

A writable IO that is the command's standard input

pid

The process identifier for the command.

static VALUE
pty_getpty(int argc, VALUE *argv, VALUE self)
{
    VALUE res;
    struct pty_info info;
    rb_io_t *wfptr,*rfptr;
    VALUE rport = rb_obj_alloc(rb_cFile);
    VALUE wport = rb_obj_alloc(rb_cFile);
    char SlaveName[DEVICELEN];

    MakeOpenFile(rport, rfptr);
    MakeOpenFile(wport, wfptr);

    establishShell(argc, argv, &info, SlaveName);

    rfptr->mode = rb_io_mode_flags("r");
    rfptr->fd = info.fd;
    rfptr->pathv = rb_obj_freeze(rb_str_new_cstr(SlaveName));

    wfptr->mode = rb_io_mode_flags("w") | FMODE_SYNC;
    wfptr->fd = rb_cloexec_dup(info.fd);
    if (wfptr->fd == -1)
        rb_sys_fail("dup()");
    rb_update_max_fd(wfptr->fd);
    wfptr->pathv = rfptr->pathv;

    res = rb_ary_new2(3);
    rb_ary_store(res,0,(VALUE)rport);
    rb_ary_store(res,1,(VALUE)wport);
    rb_ary_store(res,2,PIDT2NUM(info.child_pid));

    if (rb_block_given_p()) {
        rb_ensure(rb_yield, res, pty_detach_process, (VALUE)&info);
        return Qnil;
    }
    return res;
}


class PTY::ChildExited - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PTY::ChildExited

Thrown when PTY.check is called for a pid that represents a process that has exited.

In Files

  • ext/pty/pty.c

Parent

RuntimeError

Public Instance Methods

status() click to toggle source

Returns the exit status of the child for which PTY#check raised this exception

static VALUE
echild_status(VALUE self)
{
    return rb_ivar_get(self, rb_intern("status"));
}


class ParallelEach - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class ParallelEach

This file is imported from the minitest project. DO NOT make modifications in this repo. They will be reverted! File a patch instead and assign it to Ryan Davis.

In Files

  • lib/minitest/parallel_each.rb

Parent

Object

Included Modules

  • Enumerable

Constants

N

Public Class Methods

new(list) click to toggle source
# File lib/minitest/parallel_each.rb, line 13
def initialize list
  @queue = Queue.new # *sigh*... the Queue api sucks sooo much...

  list.each { |i| @queue << i }
  N.times { @queue << nil }
end

Public Instance Methods

each() { |job| ... } click to toggle source
# File lib/minitest/parallel_each.rb, line 24
def each
  threads = N.times.map {
    Thread.new do
      Thread.current.abort_on_exception = true
      while job = @queue.pop
        yield job
      end
    end
  }
  threads.map(&:join)
end
grep(pattern) click to toggle source
# File lib/minitest/parallel_each.rb, line 20
def grep pattern
  self.class.new super
end


class Pathname - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Pathname

Pathname represents the name of a file or directory on the filesystem, but not the file itself.

The pathname depends on the Operating System: Unix, Windows, etc. This library works with pathnames of local OS, however non-Unix pathnames are supported experimentally.

A Pathname can be relative or absolute. It's not until you try to reference the file that it even matters whether the file exists or not.

Pathname is immutable. It has no method for destructive update.

The goal of this class is to manipulate file path information in a neater way than standard Ruby provides. The examples below demonstrate the difference.

All functionality from File, FileTest, and some from Dir and FileUtils is included, in an unsurprising way. It is essentially a facade for all of these, and more.

Examples

Example 1: Using Pathname

require 'pathname'
pn = Pathname.new("/usr/bin/ruby")
size = pn.size              # 27662
isdir = pn.directory?       # false
dir  = pn.dirname           # Pathname:/usr/bin
base = pn.basename          # Pathname:ruby
dir, base = pn.split        # [Pathname:/usr/bin, Pathname:ruby]
data = pn.read
pn.open { |f| _ }
pn.each_line { |line| _ }

Example 2: Using standard Ruby

pn = "/usr/bin/ruby"
size = File.size(pn)        # 27662
isdir = File.directory?(pn) # false
dir  = File.dirname(pn)     # "/usr/bin"
base = File.basename(pn)    # "ruby"
dir, base = File.split(pn)  # ["/usr/bin", "ruby"]
data = File.read(pn)
File.open(pn) { |f| _ }
File.foreach(pn) { |line| _ }

Example 3: Special features

p1 = Pathname.new("/usr/lib")   # Pathname:/usr/lib
p2 = p1 + "ruby/1.8"            # Pathname:/usr/lib/ruby/1.8
p3 = p1.parent                  # Pathname:/usr
p4 = p2.relative_path_from(p3)  # Pathname:lib/ruby/1.8
pwd = Pathname.pwd              # Pathname:/home/gavin
pwd.absolute?                   # true
p5 = Pathname.new "."           # Pathname:.
p5 = p5 + "music/../articles"   # Pathname:music/../articles
p5.cleanpath                    # Pathname:articles
p5.realpath                     # Pathname:/home/gavin/articles
p5.children                     # [Pathname:/home/gavin/articles/linux, ...]

Breakdown of functionality

Core methods

These methods are effectively manipulating a String, because that's all a path is. None of these access the file system except for mountpoint?, children, each_child, realdirpath and realpath.

  • +

  • join

  • parent

  • root?

  • absolute?

  • relative?

  • relative_path_from

  • each_filename

  • cleanpath

  • realpath

  • realdirpath

  • children

  • each_child

  • mountpoint?

File status predicate methods

These methods are a facade for FileTest:

  • blockdev?

  • chardev?

  • directory?

  • executable?

  • executable_real?

  • exist?

  • file?

  • grpowned?

  • owned?

  • pipe?

  • readable?

  • world_readable?

  • readable_real?

  • setgid?

  • setuid?

  • size

  • size?

  • socket?

  • sticky?

  • symlink?

  • writable?

  • world_writable?

  • writable_real?

  • zero?

File property and manipulation methods

These methods are a facade for File:

  • atime

  • ctime

  • mtime

  • chmod(mode)

  • lchmod(mode)

  • chown(owner, group)

  • lchown(owner, group)

  • fnmatch(pattern, *args)

  • fnmatch?(pattern, *args)

  • ftype

  • make_link(old)

  • open(*args, &block)

  • readlink

  • rename(to)

  • stat

  • lstat

  • make_symlink(old)

  • truncate(length)

  • utime(atime, mtime)

  • basename(*args)

  • dirname

  • extname

  • expand_path(*args)

  • split

Directory methods

These methods are a facade for Dir:

  • ::glob

  • ::getwd / ::pwd

  • rmdir

  • entries

  • each_entry(&block)

  • mkdir(*args)

  • opendir(*args)

IO

These methods are a facade for IO:

  • each_line(*args, &block)

  • read(*args)

  • binread(*args)

  • readlines(*args)

  • sysopen(*args)

Utilities

These methods are a mixture of Find, FileUtils, and others:

  • find(&block)

  • mkpath

  • rmtree

  • unlink / delete

Method documentation

As the above section shows, most of the methods in Pathname are facades. The documentation for these methods generally just says, for instance, “See FileTest.writable?”, as you should be familiar with the original method anyway, and its documentation (e.g. through ri) will contain more information. In some cases, a brief description will follow.

In Files

  • ext/pathname/lib/pathname.rb
  • ext/pathname/pathname.c

Parent

Object

Public Class Methods

getwd() click to toggle source

Returns the current working directory as a Pathname.

Pathname.getwd
    #=> #<Pathname:/home/zzak/projects/ruby>

See Dir.getwd.

static VALUE
path_s_getwd(VALUE klass)
{
    VALUE str;
    str = rb_funcall(rb_cDir, rb_intern("getwd"), 0);
    return rb_class_new_instance(1, &str, klass);
}
glob(p1, p2 = v2) click to toggle source

Returns or yields Pathname objects.

Pathname.glob("config/" "*.rb")
    #=> [#<Pathname:config/environment.rb>, #<Pathname:config/routes.rb>, ..]

See Dir.glob.

static VALUE
path_s_glob(int argc, VALUE *argv, VALUE klass)
{
    VALUE args[2];
    int n;

    n = rb_scan_args(argc, argv, "11", &args[0], &args[1]);
    if (rb_block_given_p()) {
        return rb_block_call(rb_cDir, rb_intern("glob"), n, args, glob_i, klass);
    }
    else {
        VALUE ary;
        long i;
        ary = rb_funcall2(rb_cDir, rb_intern("glob"), n, args);
        ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            VALUE elt = RARRAY_PTR(ary)[i];
            elt = rb_class_new_instance(1, &elt, klass);
            rb_ary_store(ary, i, elt);
        }
        return ary;
    }
}
new(p1) click to toggle source

Create a Pathname object from the given String (or String-like object). If path contains a NULL character (\0), an ArgumentError is raised.

static VALUE
path_initialize(VALUE self, VALUE arg)
{
    VALUE str;
    if (RB_TYPE_P(arg, T_STRING)) {
        str = arg;
    }
    else {
        str = rb_check_funcall(arg, id_to_path, 0, NULL);
        if (str == Qundef)
            str = arg;
        StringValue(str);
    }
    if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str)))
        rb_raise(rb_eArgError, "pathname contains null byte");
    str = rb_obj_dup(str);

    set_strpath(self, str);
    OBJ_INFECT(self, str);
    return self;
}
pwd() click to toggle source

Returns the current working directory as a Pathname.

Pathname.getwd
    #=> #<Pathname:/home/zzak/projects/ruby>

See Dir.getwd.

static VALUE
path_s_getwd(VALUE klass)
{
    VALUE str;
    str = rb_funcall(rb_cDir, rb_intern("getwd"), 0);
    return rb_class_new_instance(1, &str, klass);
}

Public Instance Methods

+(other) click to toggle source

Appends a pathname fragment to self to produce a new Pathname object.

p1 = Pathname.new("/usr")      # Pathname:/usr
p2 = p1 + "bin/ruby"           # Pathname:/usr/bin/ruby
p3 = p1 + "/etc/passwd"        # Pathname:/etc/passwd

This method doesn't access the file system; it is pure string manipulation.

# File ext/pathname/lib/pathname.rb, line 332
def +(other)
  other = Pathname.new(other) unless Pathname === other
  Pathname.new(plus(@path, other.to_s))
end
<=>(p1) click to toggle source

Provides a case-sensitive comparison operator for pathnames.

Pathname.new('/usr') <=> Pathname.new('/usr/bin')
    #=> -1
Pathname.new('/usr/bin') <=> Pathname.new('/usr/bin')
    #=> 0
Pathname.new('/usr/bin') <=> Pathname.new('/USR/BIN')
    #=> 1

It will return -1, 0 or 1 depending on the value of the left argument relative to the right argument. Or it will return nil if the arguments are not comparable.

static VALUE
path_cmp(VALUE self, VALUE other)
{
    VALUE s1, s2;
    char *p1, *p2;
    char *e1, *e2;
    if (!rb_obj_is_kind_of(other, rb_cPathname))
        return Qnil;
    s1 = get_strpath(self);
    s2 = get_strpath(other);
    p1 = RSTRING_PTR(s1);
    p2 = RSTRING_PTR(s2);
    e1 = p1 + RSTRING_LEN(s1);
    e2 = p2 + RSTRING_LEN(s2);
    while (p1 < e1 && p2 < e2) {
        int c1, c2;
        c1 = (unsigned char)*p1++;
        c2 = (unsigned char)*p2++;
        if (c1 == '/') c1 = '\0';
        if (c2 == '/') c2 = '\0';
        if (c1 != c2) {
            if (c1 < c2)
                return INT2FIX(-1);
            else
                return INT2FIX(1);
        }
    }
    if (p1 < e1)
        return INT2FIX(1);
    if (p2 < e2)
        return INT2FIX(-1);
    return INT2FIX(0);
}
==(p1) click to toggle source

Compare this pathname with other. The comparison is string-based. Be aware that two different paths (foo.txt and ./foo.txt) can refer to the same file.

static VALUE
path_eq(VALUE self, VALUE other)
{
    if (!rb_obj_is_kind_of(other, rb_cPathname))
        return Qfalse;
    return rb_str_equal(get_strpath(self), get_strpath(other));
}
===(p1) click to toggle source

Compare this pathname with other. The comparison is string-based. Be aware that two different paths (foo.txt and ./foo.txt) can refer to the same file.

static VALUE
path_eq(VALUE self, VALUE other)
{
    if (!rb_obj_is_kind_of(other, rb_cPathname))
        return Qfalse;
    return rb_str_equal(get_strpath(self), get_strpath(other));
}
absolute?() click to toggle source

Predicate method for testing whether a path is absolute.

It returns true if the pathname begins with a slash.

p = Pathname.new('/im/sure')
p.absolute?
    #=> true

p = Pathname.new('not/so/sure')
p.absolute?
    #=> false

# File ext/pathname/lib/pathname.rb, line 227
def absolute?
  !relative?
end
ascend() { |self| ... } click to toggle source

Iterates over and yields a new Pathname object for each element in the given path in ascending order.

Pathname.new('/path/to/some/file.rb').ascend {|v| p v}
   #<Pathname:/path/to/some/file.rb>
   #<Pathname:/path/to/some>
   #<Pathname:/path/to>
   #<Pathname:/path>
   #<Pathname:/>

Pathname.new('path/to/some/file.rb').ascend {|v| p v}
   #<Pathname:path/to/some/file.rb>
   #<Pathname:path/to/some>
   #<Pathname:path/to>
   #<Pathname:path>

It doesn't access the filesystem.

# File ext/pathname/lib/pathname.rb, line 313
def ascend
  path = @path
  yield self
  while r = chop_basename(path)
    path, = r
    break if path.empty?
    yield self.class.new(del_trailing_separator(path))
  end
end
atime → time click to toggle source

Returns the last access time for the file.

See File.atime.

static VALUE
path_atime(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("atime"), 1, get_strpath(self));
}
basename(p1 = v1) click to toggle source

Returns the last component of the path.

See File.basename.

static VALUE
path_basename(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE fext;
    if (rb_scan_args(argc, argv, "01", &fext) == 0)
        str = rb_funcall(rb_cFile, rb_intern("basename"), 1, str);
    else
        str = rb_funcall(rb_cFile, rb_intern("basename"), 2, str, fext);
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}
binread([length [, offset]]) → string click to toggle source

Returns all the bytes from the file, or the first N if specified.

See IO.binread.

static VALUE
path_binread(int argc, VALUE *argv, VALUE self)
{
    VALUE args[3];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "02", &args[1], &args[2]);
    return rb_funcall2(rb_cIO, rb_intern("binread"), 1+n, args);
}
blockdev?() click to toggle source

See FileTest.blockdev?.

static VALUE
path_blockdev_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("blockdev?"), 1, get_strpath(self));
}
chardev?() click to toggle source

See FileTest.chardev?.

static VALUE
path_chardev_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("chardev?"), 1, get_strpath(self));
}
children(with_directory=true) click to toggle source

Returns the children of the directory (files and subdirectories, not recursive) as an array of Pathname objects.

By default, the returned pathnames will have enough information to access the files. If you set with_directory to false, then the returned pathnames will contain the filename only.

For example:

pn = Pathname("/usr/lib/ruby/1.8")
pn.children
    # -> [ Pathname:/usr/lib/ruby/1.8/English.rb,
           Pathname:/usr/lib/ruby/1.8/Env.rb,
           Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ]
pn.children(false)
    # -> [ Pathname:English.rb, Pathname:Env.rb, Pathname:abbrev.rb, ... ]

Note that the results never contain the entries . and .. in the directory because they are not children.

# File ext/pathname/lib/pathname.rb, line 422
def children(with_directory=true)
  with_directory = false if @path == '.'
  result = []
  Dir.foreach(@path) {|e|
    next if e == '.' || e == '..'
    if with_directory
      result << self.class.new(File.join(@path, e))
    else
      result << self.class.new(e)
    end
  }
  result
end
chmod → integer click to toggle source

Changes file permissions.

See File.chmod.

static VALUE
path_chmod(VALUE self, VALUE mode)
{
    return rb_funcall(rb_cFile, rb_intern("chmod"), 2, mode, get_strpath(self));
}
chown → integer click to toggle source

Change owner and group of the file.

See File.chown.

static VALUE
path_chown(VALUE self, VALUE owner, VALUE group)
{
    return rb_funcall(rb_cFile, rb_intern("chown"), 3, owner, group, get_strpath(self));
}
cleanpath(consider_symlink=false) click to toggle source

Returns clean pathname of self with consecutive slashes and useless dots removed. The filesystem is not accessed.

If consider_symlink is true, then a more conservative algorithm is used to avoid breaking symbolic linkages. This may retain more .. entries than absolutely necessary, but without accessing the filesystem, this can't be avoided.

See #realpath.

# File ext/pathname/lib/pathname.rb, line 87
def cleanpath(consider_symlink=false)
  if consider_symlink
    cleanpath_conservative
  else
    cleanpath_aggressive
  end
end
ctime → time click to toggle source

Returns the last change time, using directory information, not the file itself.

See File.ctime.

static VALUE
path_ctime(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("ctime"), 1, get_strpath(self));
}
delete() click to toggle source

Removes a file or directory, using File.unlink if self is a file, or Dir.unlink as necessary.

static VALUE
path_unlink(VALUE self)
{
    VALUE eENOTDIR = rb_const_get_at(rb_mErrno, rb_intern("ENOTDIR"));
    VALUE str = get_strpath(self);
    return rb_rescue2(unlink_body, str, unlink_rescue, str, eENOTDIR, (VALUE)0);
}
descend() { |v| ... } click to toggle source

Iterates over and yields a new Pathname object for each element in the given path in descending order.

Pathname.new('/path/to/some/file.rb').descend {|v| p v}
   #<Pathname:/>
   #<Pathname:/path>
   #<Pathname:/path/to>
   #<Pathname:/path/to/some>
   #<Pathname:/path/to/some/file.rb>

Pathname.new('path/to/some/file.rb').descend {|v| p v}
   #<Pathname:path>
   #<Pathname:path/to>
   #<Pathname:path/to/some>
   #<Pathname:path/to/some/file.rb>

It doesn't access the filesystem.

# File ext/pathname/lib/pathname.rb, line 288
def descend
  vs = []
  ascend {|v| vs << v }
  vs.reverse_each {|v| yield v }
  nil
end
directory?() click to toggle source

See FileTest.directory?.

static VALUE
path_directory_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("directory?"), 1, get_strpath(self));
}
dirname() click to toggle source

Returns all but the last component of the path.

See File.dirname.

static VALUE
path_dirname(VALUE self)
{
    VALUE str = get_strpath(self);
    str = rb_funcall(rb_cFile, rb_intern("dirname"), 1, str);
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}
each_child(with_directory=true, &b) click to toggle source

Iterates over the children of the directory (files and subdirectories, not recursive).

It yields Pathname object for each child.

By default, the yielded pathnames will have enough information to access the files.

If you set with_directory to false, then the returned pathnames will contain the filename only.

Pathname("/usr/local").each_child {|f| p f }
#=> #<Pathname:/usr/local/share>
#   #<Pathname:/usr/local/bin>
#   #<Pathname:/usr/local/games>
#   #<Pathname:/usr/local/lib>
#   #<Pathname:/usr/local/include>
#   #<Pathname:/usr/local/sbin>
#   #<Pathname:/usr/local/src>
#   #<Pathname:/usr/local/man>

Pathname("/usr/local").each_child(false) {|f| p f }
#=> #<Pathname:share>
#   #<Pathname:bin>
#   #<Pathname:games>
#   #<Pathname:lib>
#   #<Pathname:include>
#   #<Pathname:sbin>
#   #<Pathname:src>
#   #<Pathname:man>

Note that the results never contain the entries . and .. in the directory because they are not children.

See #children

# File ext/pathname/lib/pathname.rb, line 472
def each_child(with_directory=true, &b)
  children(with_directory).each(&b)
end
each_entry() click to toggle source

Iterates over the entries (files and subdirectories) in the directory, yielding a Pathname object for each entry.

static VALUE
path_each_entry(VALUE self)
{
    VALUE args[1];

    args[0] = get_strpath(self);
    return rb_block_call(rb_cDir, rb_intern("foreach"), 1, args, each_entry_i, rb_obj_class(self));
}
each_filename() { |filename| ... } click to toggle source

Iterates over each component of the path.

Pathname.new("/usr/bin/ruby").each_filename {|filename| ... }
  # yields "usr", "bin", and "ruby".

Returns an Enumerator if no block was given.

enum = Pathname.new("/usr/bin/ruby").each_filename
  # ... do stuff ...
enum.each { |e| ... }
  # yields "usr", "bin", and "ruby".

# File ext/pathname/lib/pathname.rb, line 263
def each_filename # :yield: filename
  return to_enum(__method__) unless block_given?
  _, names = split_names(@path)
  names.each {|filename| yield filename }
  nil
end
each_line {|line| ... } click to toggle source
each_line(sep=$/ [, open_args]) {|line| block } → nil
each_line(limit [, open_args]) {|line| block } → nil
each_line(sep, limit [, open_args]) {|line| block } → nil
each_line(...) → an_enumerator

Iterates over each line in the file and yields a String object for each.

static VALUE
path_each_line(int argc, VALUE *argv, VALUE self)
{
    VALUE args[4];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
    if (rb_block_given_p()) {
        return rb_block_call(rb_cIO, rb_intern("foreach"), 1+n, args, 0, 0);
    }
    else {
        return rb_funcall2(rb_cIO, rb_intern("foreach"), 1+n, args);
    }
}
entries() click to toggle source

Return the entries (files and subdirectories) in the directory, each as a Pathname object.

The results contains just the names in the directory, without any trailing slashes or recursive look-up.

pp Pathname.new('/usr/local').entries
#=> [#<Pathname:share>,
#    #<Pathname:lib>,
#    #<Pathname:..>,
#    #<Pathname:include>,
#    #<Pathname:etc>,
#    #<Pathname:bin>,
#    #<Pathname:man>,
#    #<Pathname:games>,
#    #<Pathname:.>,
#    #<Pathname:sbin>,
#    #<Pathname:src>]

The result may contain the current directory #<Pathname:.> and the parent directory #<Pathname:..>.

If you don't want . and .. and want directories, consider #children.

static VALUE
path_entries(VALUE self)
{
    VALUE klass, str, ary;
    long i;
    klass = rb_obj_class(self);
    str = get_strpath(self);
    ary = rb_funcall(rb_cDir, rb_intern("entries"), 1, str);
    ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        VALUE elt = RARRAY_PTR(ary)[i];
        elt = rb_class_new_instance(1, &elt, klass);
        rb_ary_store(ary, i, elt);
    }
    return ary;
}
eql?(p1) click to toggle source

Compare this pathname with other. The comparison is string-based. Be aware that two different paths (foo.txt and ./foo.txt) can refer to the same file.

static VALUE
path_eq(VALUE self, VALUE other)
{
    if (!rb_obj_is_kind_of(other, rb_cPathname))
        return Qfalse;
    return rb_str_equal(get_strpath(self), get_strpath(other));
}
executable?() click to toggle source

See FileTest.executable?.

static VALUE
path_executable_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("executable?"), 1, get_strpath(self));
}
executable_real?() click to toggle source

See FileTest.executable_real?.

static VALUE
path_executable_real_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("executable_real?"), 1, get_strpath(self));
}
exist?() click to toggle source

See FileTest.exist?.

static VALUE
path_exist_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("exist?"), 1, get_strpath(self));
}
expand_path(p1 = v1) click to toggle source

Returns the absolute path for the file.

See File.expand_path.

static VALUE
path_expand_path(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE dname;
    if (rb_scan_args(argc, argv, "01", &dname) == 0)
        str = rb_funcall(rb_cFile, rb_intern("expand_path"), 1, str);
    else
        str = rb_funcall(rb_cFile, rb_intern("expand_path"), 2, str, dname);
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}
extname() click to toggle source

Returns the file's extension.

See File.extname.

static VALUE
path_extname(VALUE self)
{
    VALUE str = get_strpath(self);
    return rb_funcall(rb_cFile, rb_intern("extname"), 1, str);
}
file?() click to toggle source

See FileTest.file?.

static VALUE
path_file_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("file?"), 1, get_strpath(self));
}
find() { |pathname| ... } click to toggle source

Iterates over the directory tree in a depth first manner, yielding a Pathname for each file under “this” directory.

Returns an Enumerator if no block is given.

Since it is implemented by the standard library module Find, Find.prune can be used to control the traversal.

If self is ., yielded pathnames begin with a filename in the current directory, not ./.

See Find.find

# File ext/pathname/lib/pathname.rb, line 540
def find # :yield: pathname
  return to_enum(__method__) unless block_given?
  require 'find'
  if @path == '.'
    Find.find(@path) {|f| yield self.class.new(f.sub(%r{\A\./}, '')) }
  else
    Find.find(@path) {|f| yield self.class.new(f) }
  end
end
fnmatch(pattern, [flags]) → string click to toggle source
fnmatch?(pattern, [flags]) → string

Return true if the receiver matches the given pattern.

See File.fnmatch.

static VALUE
path_fnmatch(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE pattern, flags;
    if (rb_scan_args(argc, argv, "11", &pattern, &flags) == 1)
        return rb_funcall(rb_cFile, rb_intern("fnmatch"), 2, pattern, str);
    else
        return rb_funcall(rb_cFile, rb_intern("fnmatch"), 3, pattern, str, flags);
}
fnmatch(pattern, [flags]) → string click to toggle source
fnmatch?(pattern, [flags]) → string

Return true if the receiver matches the given pattern.

See File.fnmatch.

static VALUE
path_fnmatch(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE pattern, flags;
    if (rb_scan_args(argc, argv, "11", &pattern, &flags) == 1)
        return rb_funcall(rb_cFile, rb_intern("fnmatch"), 2, pattern, str);
    else
        return rb_funcall(rb_cFile, rb_intern("fnmatch"), 3, pattern, str, flags);
}
freeze → obj click to toggle source

Freezes this Pathname.

See Object.freeze.

static VALUE
path_freeze(VALUE self)
{
    rb_call_super(0, 0);
    rb_str_freeze(get_strpath(self));
    return self;
}
ftype → string click to toggle source

Returns “type” of file (“file”, “directory”, etc).

See File.ftype.

static VALUE
path_ftype(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("ftype"), 1, get_strpath(self));
}
grpowned?() click to toggle source

See FileTest.grpowned?.

static VALUE
path_grpowned_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("grpowned?"), 1, get_strpath(self));
}
join(*args) click to toggle source

Joins the given pathnames onto self to create a new Pathname object.

path0 = Pathname.new("/usr")                # Pathname:/usr
path0 = path0.join("bin/ruby")              # Pathname:/usr/bin/ruby
    # is the same as
path1 = Pathname.new("/usr") + "bin/ruby"   # Pathname:/usr/bin/ruby
path0 == path1
    #=> true

# File ext/pathname/lib/pathname.rb, line 389
def join(*args)
  args.unshift self
  result = args.pop
  result = Pathname.new(result) unless Pathname === result
  return result if result.absolute?
  args.reverse_each {|arg|
    arg = Pathname.new(arg) unless Pathname === arg
    result = arg + result
    return result if result.absolute?
  }
  result
end
lchmod → integer click to toggle source

Same as #chmod, but does not follow symbolic links.

See File.lchmod.

static VALUE
path_lchmod(VALUE self, VALUE mode)
{
    return rb_funcall(rb_cFile, rb_intern("lchmod"), 2, mode, get_strpath(self));
}
lchown → integer click to toggle source

Same as #chown, but does not follow symbolic links.

See File.lchown.

static VALUE
path_lchown(VALUE self, VALUE owner, VALUE group)
{
    return rb_funcall(rb_cFile, rb_intern("lchown"), 3, owner, group, get_strpath(self));
}
lstat() click to toggle source

See File.lstat.

static VALUE
path_lstat(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("lstat"), 1, get_strpath(self));
}
make_link(old) click to toggle source

Creates a hard link at pathname.

See File.link.

static VALUE
path_make_link(VALUE self, VALUE old)
{
    return rb_funcall(rb_cFile, rb_intern("link"), 2, old, get_strpath(self));
}
make_symlink(old) click to toggle source

Creates a symbolic link.

See File.symlink.

static VALUE
path_make_symlink(VALUE self, VALUE old)
{
    return rb_funcall(rb_cFile, rb_intern("symlink"), 2, old, get_strpath(self));
}
mkdir(p1 = v1) click to toggle source

Create the referenced directory.

See Object#mkdir.

static VALUE
path_mkdir(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE vmode;
    if (rb_scan_args(argc, argv, "01", &vmode) == 0)
        return rb_funcall(rb_cDir, rb_intern("mkdir"), 1, str);
    else
        return rb_funcall(rb_cDir, rb_intern("mkdir"), 2, str, vmode);
}
mkpath() click to toggle source

Creates a full path, including any intermediate directories that don't yet exist.

See FileUtils.mkpath and FileUtils.mkdir_p

# File ext/pathname/lib/pathname.rb, line 557
def mkpath
  require 'fileutils'
  FileUtils.mkpath(@path)
  nil
end
mountpoint?() click to toggle source

Returns true if self points to a mountpoint.

# File ext/pathname/lib/pathname.rb, line 194
def mountpoint?
  begin
    stat1 = self.lstat
    stat2 = self.parent.lstat
    stat1.dev == stat2.dev && stat1.ino == stat2.ino ||
      stat1.dev != stat2.dev
  rescue Errno::ENOENT
    false
  end
end
mtime → time click to toggle source

Returns the last modified time of the file.

See File.mtime.

static VALUE
path_mtime(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("mtime"), 1, get_strpath(self));
}
open(p1 = v1, p2 = v2, p3 = v3) click to toggle source

Opens the file for reading or writing.

See File.open.

static VALUE
path_open(int argc, VALUE *argv, VALUE self)
{
    VALUE args[4];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
    if (rb_block_given_p()) {
        return rb_block_call(rb_cFile, rb_intern("open"), 1+n, args, 0, 0);
    }
    else {
        return rb_funcall2(rb_cFile, rb_intern("open"), 1+n, args);
    }
}
opendir() click to toggle source

Opens the referenced directory.

See Dir.open.

static VALUE
path_opendir(VALUE self)
{
    VALUE args[1];

    args[0] = get_strpath(self);
    return rb_block_call(rb_cDir, rb_intern("open"), 1, args, 0, 0);
}
owned?() click to toggle source

See FileTest.owned?.

static VALUE
path_owned_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("owned?"), 1, get_strpath(self));
}
parent() click to toggle source

Returns the parent directory.

This is same as self + '..'.

# File ext/pathname/lib/pathname.rb, line 189
def parent
  self + '..'
end
pipe?() click to toggle source

See FileTest.pipe?.

static VALUE
path_pipe_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("pipe?"), 1, get_strpath(self));
}
read([length [, offset]]) → string click to toggle source
read([length [, offset]], open_args) → string

Returns all data from the file, or the first N bytes if specified.

See IO.read.

static VALUE
path_read(int argc, VALUE *argv, VALUE self)
{
    VALUE args[4];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
    return rb_funcall2(rb_cIO, rb_intern("read"), 1+n, args);
}
readable?() click to toggle source

See FileTest.readable?.

static VALUE
path_readable_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("readable?"), 1, get_strpath(self));
}
readable_real?() click to toggle source

See FileTest.readable_real?.

static VALUE
path_readable_real_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("readable_real?"), 1, get_strpath(self));
}
readlines(sep=$/ [, open_args]) → array click to toggle source
readlines(limit [, open_args]) → array
readlines(sep, limit [, open_args]) → array

Returns all the lines from the file.

See IO.readlines.

static VALUE
path_readlines(int argc, VALUE *argv, VALUE self)
{
    VALUE args[4];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
    return rb_funcall2(rb_cIO, rb_intern("readlines"), 1+n, args);
}
readlink() click to toggle source

Read symbolic link.

See File.readlink.

static VALUE
path_readlink(VALUE self)
{
    VALUE str;
    str = rb_funcall(rb_cFile, rb_intern("readlink"), 1, get_strpath(self));
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}
realdirpath(p1 = v1) click to toggle source

Returns the real (absolute) pathname of self in the actual filesystem.

Does not contain symlinks or useless dots, .. and ..

The last component of the real pathname can be nonexistent.

static VALUE
path_realdirpath(int argc, VALUE *argv, VALUE self)
{
    VALUE basedir, str;
    rb_scan_args(argc, argv, "01", &basedir);
    str = rb_funcall(rb_cFile, rb_intern("realdirpath"), 2, get_strpath(self), basedir);
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}
realpath(p1 = v1) click to toggle source

Returns the real (absolute) pathname for self in the actual filesystem.

Does not contain symlinks or useless dots, .. and ..

All components of the pathname must exist when this method is called.

static VALUE
path_realpath(int argc, VALUE *argv, VALUE self)
{
    VALUE basedir, str;
    rb_scan_args(argc, argv, "01", &basedir);
    str = rb_funcall(rb_cFile, rb_intern("realpath"), 2, get_strpath(self), basedir);
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}
relative?() click to toggle source

The opposite of #absolute?

It returns false if the pathname begins with a slash.

p = Pathname.new('/im/sure')
p.relative?
    #=> false

p = Pathname.new('not/so/sure')
p.relative?
    #=> true

# File ext/pathname/lib/pathname.rb, line 242
def relative?
  path = @path
  while r = chop_basename(path)
    path, = r
  end
  path == ''
end
relative_path_from(base_directory) click to toggle source

Returns a relative path from the given base_directory to the receiver.

If self is absolute, then base_directory must be absolute too.

If self is relative, then base_directory must be relative too.

This method doesn't access the filesystem. It assumes no symlinks.

ArgumentError is raised when it cannot find a relative path.

# File ext/pathname/lib/pathname.rb, line 487
def relative_path_from(base_directory)
  dest_directory = self.cleanpath.to_s
  base_directory = base_directory.cleanpath.to_s
  dest_prefix = dest_directory
  dest_names = []
  while r = chop_basename(dest_prefix)
    dest_prefix, basename = r
    dest_names.unshift basename if basename != '.'
  end
  base_prefix = base_directory
  base_names = []
  while r = chop_basename(base_prefix)
    base_prefix, basename = r
    base_names.unshift basename if basename != '.'
  end
  unless SAME_PATHS[dest_prefix, base_prefix]
    raise ArgumentError, "different prefix: #{dest_prefix.inspect} and #{base_directory.inspect}"
  end
  while !dest_names.empty? &&
        !base_names.empty? &&
        SAME_PATHS[dest_names.first, base_names.first]
    dest_names.shift
    base_names.shift
  end
  if base_names.include? '..'
    raise ArgumentError, "base_directory has ..: #{base_directory.inspect}"
  end
  base_names.fill('..')
  relpath_names = base_names + dest_names
  if relpath_names.empty?
    Pathname.new('.')
  else
    Pathname.new(File.join(*relpath_names))
  end
end
rename(p1) click to toggle source

Rename the file.

See File.rename.

static VALUE
path_rename(VALUE self, VALUE to)
{
    return rb_funcall(rb_cFile, rb_intern("rename"), 2, get_strpath(self), to);
}
rmdir() click to toggle source

Remove the referenced directory.

See Object#rmdir.

static VALUE
path_rmdir(VALUE self)
{
    return rb_funcall(rb_cDir, rb_intern("rmdir"), 1, get_strpath(self));
}
rmtree() click to toggle source

Recursively deletes a directory, including all directories beneath it.

See FileUtils.rm_r

# File ext/pathname/lib/pathname.rb, line 566
def rmtree
  # The name "rmtree" is borrowed from File::Path of Perl.
  # File::Path provides "mkpath" and "rmtree".
  require 'fileutils'
  FileUtils.rm_r(@path)
  nil
end
root?() click to toggle source

Predicate method for root directories. Returns true if the pathname consists of consecutive slashes.

It doesn't access the filesystem. So it may return false for some pathnames which points to roots such as /usr/...

# File ext/pathname/lib/pathname.rb, line 212
def root?
  !!(chop_basename(@path) == nil && /#{SEPARATOR_PAT}/ =~ @path)
end
setgid?() click to toggle source

See FileTest.setgid?.

static VALUE
path_setgid_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("setgid?"), 1, get_strpath(self));
}
setuid?() click to toggle source

See FileTest.setuid?.

static VALUE
path_setuid_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("setuid?"), 1, get_strpath(self));
}
size() click to toggle source

See FileTest.size.

static VALUE
path_size(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("size"), 1, get_strpath(self));
}
size?() click to toggle source

See FileTest.size?.

static VALUE
path_size_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("size?"), 1, get_strpath(self));
}
socket?() click to toggle source

See FileTest.socket?.

static VALUE
path_socket_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("socket?"), 1, get_strpath(self));
}
split() click to toggle source

Returns the dirname and the basename in an Array.

See File.split.

static VALUE
path_split(VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE ary, dirname, basename;
    ary = rb_funcall(rb_cFile, rb_intern("split"), 1, str);
    ary = rb_check_array_type(ary);
    dirname = rb_ary_entry(ary, 0);
    basename = rb_ary_entry(ary, 1);
    dirname = rb_class_new_instance(1, &dirname, rb_obj_class(self));
    basename = rb_class_new_instance(1, &basename, rb_obj_class(self));
    return rb_ary_new3(2, dirname, basename);
}
stat() click to toggle source

Returns a File::Stat object.

See File.stat.

static VALUE
path_stat(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("stat"), 1, get_strpath(self));
}
sticky?() click to toggle source

See FileTest.sticky?.

static VALUE
path_sticky_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("sticky?"), 1, get_strpath(self));
}
sub(*args) click to toggle source

Return a pathname which is substituted by String#sub.

path1 = Pathname.new('/usr/bin/perl')
path1.sub('perl', 'ruby')
    #=> #<Pathname:/usr/bin/ruby>

static VALUE
path_sub(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);

    if (rb_block_given_p()) {
        str = rb_block_call(str, rb_intern("sub"), argc, argv, 0, 0);
    }
    else {
        str = rb_funcall2(str, rb_intern("sub"), argc, argv);
    }
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}
sub_ext(p1) click to toggle source

Return a pathname with repl added as a suffix to the basename.

If self has no extension part, repl is appended.

Pathname.new('/usr/bin/shutdown').sub_ext('.rb')
    #=> #<Pathname:/usr/bin/shutdown.rb>

static VALUE
path_sub_ext(VALUE self, VALUE repl)
{
    VALUE str = get_strpath(self);
    VALUE str2;
    long extlen;
    const char *ext;
    const char *p;

    StringValue(repl);
    p = RSTRING_PTR(str);
    extlen = RSTRING_LEN(str);
    ext = ruby_enc_find_extname(p, &extlen, rb_enc_get(str));
    if (ext == NULL) {
        ext = p + RSTRING_LEN(str);
    }
    else if (extlen <= 1) {
        ext += extlen;
    }
    str2 = rb_str_subseq(str, 0, ext-p);
    rb_str_append(str2, repl);
    OBJ_INFECT(str2, str);
    return rb_class_new_instance(1, &str2, rb_obj_class(self));
}
symlink?() click to toggle source

See FileTest.symlink?.

static VALUE
path_symlink_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("symlink?"), 1, get_strpath(self));
}
sysopen([mode, [perm]]) → fixnum click to toggle source

See IO.sysopen.

static VALUE
path_sysopen(int argc, VALUE *argv, VALUE self)
{
    VALUE args[3];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "02", &args[1], &args[2]);
    return rb_funcall2(rb_cIO, rb_intern("sysopen"), 1+n, args);
}
taint → obj click to toggle source

Taints this Pathname.

See Object.taint.

static VALUE
path_taint(VALUE self)
{
    rb_call_super(0, 0);
    rb_obj_taint(get_strpath(self));
    return self;
}
to_s → string click to toggle source
to_path → string

Return the path as a String.

#to_path is implemented so Pathname objects are usable with File.open, etc.

static VALUE
path_to_s(VALUE self)
{
    return rb_obj_dup(get_strpath(self));
}
to_s → string click to toggle source
to_path → string

Return the path as a String.

#to_path is implemented so Pathname objects are usable with File.open, etc.

static VALUE
path_to_s(VALUE self)
{
    return rb_obj_dup(get_strpath(self));
}
truncate(p1) click to toggle source

Truncates the file to length bytes.

See File.truncate.

static VALUE
path_truncate(VALUE self, VALUE length)
{
    return rb_funcall(rb_cFile, rb_intern("truncate"), 2, get_strpath(self), length);
}
unlink() click to toggle source

Removes a file or directory, using File.unlink if self is a file, or Dir.unlink as necessary.

static VALUE
path_unlink(VALUE self)
{
    VALUE eENOTDIR = rb_const_get_at(rb_mErrno, rb_intern("ENOTDIR"));
    VALUE str = get_strpath(self);
    return rb_rescue2(unlink_body, str, unlink_rescue, str, eENOTDIR, (VALUE)0);
}
untaint → obj click to toggle source

Untaints this Pathname.

See Object.untaint.

static VALUE
path_untaint(VALUE self)
{
    rb_call_super(0, 0);
    rb_obj_untaint(get_strpath(self));
    return self;
}
utime(p1, p2) click to toggle source

Update the access and modification times of the file.

See File.utime.

static VALUE
path_utime(VALUE self, VALUE atime, VALUE mtime)
{
    return rb_funcall(rb_cFile, rb_intern("utime"), 3, atime, mtime, get_strpath(self));
}
world_readable?() click to toggle source

See FileTest.world_readable?.

static VALUE
path_world_readable_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("world_readable?"), 1, get_strpath(self));
}
world_writable?() click to toggle source

See FileTest.world_writable?.

static VALUE
path_world_writable_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("world_writable?"), 1, get_strpath(self));
}
writable?() click to toggle source

See FileTest.writable?.

static VALUE
path_writable_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("writable?"), 1, get_strpath(self));
}
writable_real?() click to toggle source

See FileTest.writable_real?.

static VALUE
path_writable_real_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("writable_real?"), 1, get_strpath(self));
}
zero?() click to toggle source

See FileTest.zero?.

static VALUE
path_zero_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("zero?"), 1, get_strpath(self));
}


class PrettyPrint - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PrettyPrint

This class implements a pretty printing algorithm. It finds line breaks and nice indentations for grouped structure.

By default, the class assumes that primitive elements are strings and each byte in the strings have single column in width. But it can be used for other situations by giving suitable arguments for some methods:

  • newline object and space generation block for ::new

  • optional width argument for #text

  • #breakable

There are several candidate uses:

  • text formatting using proportional fonts

  • multibyte characters which has columns different to number of bytes

  • non-string formatting

Bugs

  • Box based formatting?

  • Other (better) model/algorithm?

References

Christian Lindig, Strictly Pretty, March 2000, www.st.cs.uni-sb.de/~lindig/papers/#pretty

Philip Wadler, A prettier printer, March 1998, homepages.inf.ed.ac.uk/wadler/topics/language-design.html#prettier

Author

Tanaka Akira <akr@m17n.org>

In Files

  • lib/prettyprint.rb

Parent

Object

Attributes

genspace[R]
group_queue[R]
indent[R]
maxwidth[R]
newline[R]
output[R]

Public Class Methods

format(output='', maxwidth=79, newline="\n", genspace=lambda {|n| ' ' * n}) { |q| ... } click to toggle source

This is a convenience method which is same as follows:

begin
  q = PrettyPrint.new(output, maxwidth, newline, &genspace)
  ...
  q.flush
  output
end
# File lib/prettyprint.rb, line 41
def PrettyPrint.format(output='', maxwidth=79, newline="\n", genspace=lambda {|n| ' ' * n})
  q = PrettyPrint.new(output, maxwidth, newline, &genspace)
  yield q
  q.flush
  output
end
new(output='', maxwidth=79, newline="\n", &genspace) click to toggle source

Creates a buffer for pretty printing.

output is an output target. If it is not specified, '' is assumed. It should have a << method which accepts the first argument obj of #text, the first argument sep of #breakable, the first argument newline of ::new, and the result of a given block for ::new.

maxwidth specifies maximum line length. If it is not specified, 79 is assumed. However actual outputs may overflow maxwidth if long non-breakable texts are provided.

newline is used for line breaks. “n” is used if it is not specified.

The block is used to generate spaces. {|width| ' ' * width} is used if it is not given.

# File lib/prettyprint.rb, line 78
def initialize(output='', maxwidth=79, newline="\n", &genspace)
  @output = output
  @maxwidth = maxwidth
  @newline = newline
  @genspace = genspace || lambda {|n| ' ' * n}

  @output_width = 0
  @buffer_width = 0
  @buffer = []

  root_group = Group.new(0)
  @group_stack = [root_group]
  @group_queue = GroupQueue.new(root_group)
  @indent = 0
end
singleline_format(output='', maxwidth=nil, newline=nil, genspace=nil) { |q| ... } click to toggle source

This is similar to ::format but the result has no breaks.

maxwidth, newline and genspace are ignored.

The invocation of breakable in the block doesn't break a line and is treated as just an invocation of text.

# File lib/prettyprint.rb, line 55
def PrettyPrint.singleline_format(output='', maxwidth=nil, newline=nil, genspace=nil)
  q = SingleLine.new(output)
  yield q
  output
end

Public Instance Methods

break_outmost_groups() click to toggle source

Breaks the buffer into lines that are shorter than maxwidth

# File lib/prettyprint.rb, line 124
def break_outmost_groups
  while @maxwidth < @output_width + @buffer_width
    return unless group = @group_queue.deq
    until group.breakables.empty?
      data = @buffer.shift
      @output_width = data.output(@output, @output_width)
      @buffer_width -= data.width
    end
    while !@buffer.empty? && Text === @buffer.first
      text = @buffer.shift
      @output_width = text.output(@output, @output_width)
      @buffer_width -= text.width
    end
  end
end
breakable(sep=' ', width=sep.length) click to toggle source

This says “you can break a line here if necessary”, and a width-column text sep is inserted if a line is not broken at the point.

If sep is not specified, “ ” is used.

If width is not specified, sep.length is used. You will have to specify this when sep is a multibyte character, for example.

# File lib/prettyprint.rb, line 188
def breakable(sep=' ', width=sep.length)
  group = @group_stack.last
  if group.break?
    flush
    @output << @newline
    @output << @genspace.call(@indent)
    @output_width = @indent
    @buffer_width = 0
  else
    @buffer << Breakable.new(sep, width, self)
    @buffer_width += width
    break_outmost_groups
  end
end
current_group() click to toggle source

Returns the group most recently added to the stack.

# File lib/prettyprint.rb, line 97
def current_group
  @group_stack.last
end
fill_breakable(sep=' ', width=sep.length) click to toggle source

This is similar to breakable except the decision to break or not is determined individually.

Two fill_breakable under a group may cause 4 results: (break,break), (break,non-break), (non-break,break), (non-break,non-break). This is different to breakable because two breakable under a group may cause 2 results: (break,break), (non-break,non-break).

The text sep+ is inserted if a line is not broken at this point.

If sep is not specified, “ ” is used.

If width is not specified, sep.length is used. You will have to specify this when sep is a multibyte character, for example.

# File lib/prettyprint.rb, line 176
def fill_breakable(sep=' ', width=sep.length)
  group { breakable sep, width }
end
first?() click to toggle source

first? is a predicate to test the call is a first call to first? with current group.

It is useful to format comma separated values as:

q.group(1, '[', ']') {
  xxx.each {|yyy|
    unless q.first?
      q.text ','
      q.breakable
    end
    ... pretty printing yyy ...
  }
}

first? is obsoleted in 1.8.2.

# File lib/prettyprint.rb, line 118
def first?
  warn "PrettyPrint#first? is obsoleted at 1.8.2."
  current_group.first?
end
flush() click to toggle source

outputs buffered data.

# File lib/prettyprint.rb, line 251
def flush
  @buffer.each {|data|
    @output_width = data.output(@output, @output_width)
  }
  @buffer.clear
  @buffer_width = 0
end
group(indent=0, open_obj='', close_obj='', open_width=open_obj.length, close_width=close_obj.length) { || ... } click to toggle source

Groups line break hints added in the block. The line break hints are all to be used or not.

If indent is specified, the method call is regarded as nested by nest(indent) { … }.

If open_obj is specified, text open_obj, open_width is called before grouping. If close_obj is specified, text close_obj, close_width is called after grouping.

# File lib/prettyprint.rb, line 213
def group(indent=0, open_obj='', close_obj='', open_width=open_obj.length, close_width=close_obj.length)
  text open_obj, open_width
  group_sub {
    nest(indent) {
      yield
    }
  }
  text close_obj, close_width
end
group_sub() { || ... } click to toggle source
# File lib/prettyprint.rb, line 223
def group_sub
  group = Group.new(@group_stack.last.depth + 1)
  @group_stack.push group
  @group_queue.enq group
  begin
    yield
  ensure
    @group_stack.pop
    if group.breakables.empty?
      @group_queue.delete group
    end
  end
end
nest(indent) { || ... } click to toggle source

Increases left margin after newline with indent for line breaks added in the block.

# File lib/prettyprint.rb, line 240
def nest(indent)
  @indent += indent
  begin
    yield
  ensure
    @indent -= indent
  end
end
text(obj, width=obj.length) click to toggle source

This adds obj as a text of width columns in width.

If width is not specified, obj.length is used.

# File lib/prettyprint.rb, line 144
def text(obj, width=obj.length)
  if @buffer.empty?
    @output << obj
    @output_width += width
  else
    text = @buffer.last
    unless Text === text
      text = Text.new
      @buffer << text
    end
    text.add(obj, width)
    @buffer_width += width
    break_outmost_groups
  end
end


class PrettyPrint::Breakable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PrettyPrint::Breakable

In Files

  • lib/prettyprint.rb

Parent

Object

Attributes

indent[R]
obj[R]
width[R]

Public Class Methods

new(sep, width, q) click to toggle source
# File lib/prettyprint.rb, line 278
def initialize(sep, width, q)
  @obj = sep
  @width = width
  @pp = q
  @indent = q.indent
  @group = q.current_group
  @group.breakables.push self
end

Public Instance Methods

output(out, output_width) click to toggle source
# File lib/prettyprint.rb, line 288
def output(out, output_width)
  @group.breakables.shift
  if @group.break?
    out << @pp.newline
    out << @pp.genspace.call(@indent)
    @indent
  else
    @pp.group_queue.delete @group if @group.breakables.empty?
    out << @obj
    output_width + @width
  end
end


class PrettyPrint::Group - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PrettyPrint::Group

In Files

  • lib/prettyprint.rb

Parent

Object

Attributes

breakables[R]
depth[R]

Public Class Methods

new(depth) click to toggle source
# File lib/prettyprint.rb, line 303
def initialize(depth)
  @depth = depth
  @breakables = []
  @break = false
end

Public Instance Methods

break() click to toggle source
# File lib/prettyprint.rb, line 310
def break
  @break = true
end
break?() click to toggle source
# File lib/prettyprint.rb, line 314
def break?
  @break
end
first?() click to toggle source
# File lib/prettyprint.rb, line 318
def first?
  if defined? @first
    false
  else
    @first = false
    true
  end
end


class PrettyPrint::GroupQueue - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PrettyPrint::GroupQueue

In Files

  • lib/prettyprint.rb

Parent

Object

Public Class Methods

new(*groups) click to toggle source
# File lib/prettyprint.rb, line 329
def initialize(*groups)
  @queue = []
  groups.each {|g| enq g}
end

Public Instance Methods

delete(group) click to toggle source
# File lib/prettyprint.rb, line 355
def delete(group)
  @queue[group.depth].delete(group)
end
deq() click to toggle source
# File lib/prettyprint.rb, line 340
def deq
  @queue.each {|gs|
    (gs.length-1).downto(0) {|i|
      unless gs[i].breakables.empty?
        group = gs.slice!(i, 1).first
        group.break
        return group
      end
    }
    gs.each {|group| group.break}
    gs.clear
  }
  return nil
end
enq(group) click to toggle source
# File lib/prettyprint.rb, line 334
def enq(group)
  depth = group.depth
  @queue << [] until depth < @queue.length
  @queue[depth] << group
end


class PrettyPrint::SingleLine - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PrettyPrint::SingleLine

In Files

  • lib/prettyprint.rb

Parent

Object

Public Class Methods

new(output, maxwidth=nil, newline=nil) click to toggle source
# File lib/prettyprint.rb, line 361
def initialize(output, maxwidth=nil, newline=nil)
  @output = output
  @first = [true]
end

Public Instance Methods

breakable(sep=' ', width=nil) click to toggle source
# File lib/prettyprint.rb, line 370
def breakable(sep=' ', width=nil)
  @output << sep
end
first?() click to toggle source
# File lib/prettyprint.rb, line 389
def first?
  result = @first[-1]
  @first[-1] = false
  result
end
flush() click to toggle source
# File lib/prettyprint.rb, line 386
def flush
end
group(indent=nil, open_obj='', close_obj='', open_width=nil, close_width=nil) { || ... } click to toggle source
# File lib/prettyprint.rb, line 378
def group(indent=nil, open_obj='', close_obj='', open_width=nil, close_width=nil)
  @first.push true
  @output << open_obj
  yield
  @output << close_obj
  @first.pop
end
nest(indent) { || ... } click to toggle source
# File lib/prettyprint.rb, line 374
def nest(indent)
  yield
end
text(obj, width=nil) click to toggle source
# File lib/prettyprint.rb, line 366
def text(obj, width=nil)
  @output << obj
end


class PrettyPrint::Text - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PrettyPrint::Text

In Files

  • lib/prettyprint.rb

Parent

Object

Attributes

width[R]

Public Class Methods

new() click to toggle source
# File lib/prettyprint.rb, line 260
def initialize
  @objs = []
  @width = 0
end

Public Instance Methods

add(obj, width) click to toggle source
# File lib/prettyprint.rb, line 271
def add(obj, width)
  @objs << obj
  @width += width
end
output(out, output_width) click to toggle source
# File lib/prettyprint.rb, line 266
def output(out, output_width)
  @objs.each {|obj| out << obj}
  output_width + @width
end


class PrideIO - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PrideIO

Show your testing pride!

In Files

  • lib/minitest/pride.rb

Parent

Object

Constants

ESC

Start an escape sequence

NND

End the escape sequence

Attributes

io[R]

The IO we're going to pipe through.

Public Instance Methods

pride(string) click to toggle source

Color a string.

# File lib/minitest/pride.rb, line 63
def pride string
  string = "*" if string == "."
  c = @colors[@index % @size]
  @index += 1
  "#{ESC}#{c}m#{string}#{NND}"
end
print(o) click to toggle source

Wrap print to colorize the output.

# File lib/minitest/pride.rb, line 36
def print o
  case o
  when "." then
    io.print pride o
  when "E", "F" then
    io.print "#{ESC}41m#{ESC}37m#{o}#{NND}"
  else
    io.print o
  end
end


class PrideLOL - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class PrideLOL

If you thought the PrideIO was colorful…

(Inspired by lolcat, but with clean math)

In Files

  • lib/minitest/pride.rb

Parent

PrideIO

Public Instance Methods

pride(string) click to toggle source

Make the string even more colorful. Damnit.

# File lib/minitest/pride.rb, line 110
def pride string
  c = @colors[@index % @size]
  @index += 1
  "#{ESC}38;5;#{c}m#{string}#{NND}"
end


class Prime - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Prime

The set of all prime numbers.

Example

Prime.each(100) do |prime|
  p prime  #=> 2, 3, 5, 7, 11, ...., 97
end

Prime is Enumerable:

Prime.first 5 # => [2, 3, 5, 7, 11]

Retrieving the instance

Prime.new is obsolete. Now Prime has the default instance and you can access it as Prime.instance.

For convenience, each instance method of Prime.instance can be accessed as a class method of Prime.

e.g.

Prime.instance.prime?(2)  #=> true
Prime.prime?(2)           #=> true

Generators

A “generator” provides an implementation of enumerating pseudo-prime numbers and it remembers the position of enumeration and upper bound. Furthermore, it is a external iterator of prime enumeration which is compatible to an Enumerator.

Prime::PseudoPrimeGenerator is the base class for generators. There are few implementations of generator.

Prime::EratosthenesGenerator

Uses eratosthenes's sieve.

Prime::TrialDivisionGenerator

Uses the trial division method.

Prime::Generator23

Generates all positive integers which is not divided by 2 nor 3. This sequence is very bad as a pseudo-prime sequence. But this is faster and uses much less memory than other generators. So, it is suitable for factorizing an integer which is not large but has many prime factors. e.g. for #prime? .

In Files

  • lib/prime.rb

Parent

Object

Included Modules

  • Enumerable

Public Class Methods

instance() click to toggle source

Returns the default instance of Prime.

# File lib/prime.rb, line 106
def instance; @the_instance end
new() click to toggle source

obsolete. Use Prime::instance or class methods of Prime.

# File lib/prime.rb, line 96
def initialize
  @generator = EratosthenesGenerator.new
  extend OldCompatibility
  warn "Prime::new is obsolete. use Prime::instance or class methods of Prime."
end

Public Instance Methods

each(ubound = nil, generator = EratosthenesGenerator.new, &block) click to toggle source

Iterates the given block over all prime numbers.

Parameters

ubound

Optional. An arbitrary positive number. The upper bound of enumeration. The method enumerates prime numbers infinitely if ubound is nil.

generator

Optional. An implementation of pseudo-prime generator.

Return value

An evaluated value of the given block at the last time. Or an enumerator which is compatible to an Enumerator if no block given.

Description

Calls block once for each prime number, passing the prime as a parameter.

ubound

Upper bound of prime numbers. The iterator stops after yields all prime numbers p <= ubound.

Note

Prime.new returns a object extended by Prime::OldCompatibility in order to compatibility to Ruby 1.8, and Prime each is overwritten by Prime::OldCompatibility#each.

Prime.new is now obsolete. Use Prime.instance.each or simply Prime.each.

# File lib/prime.rb, line 147
def each(ubound = nil, generator = EratosthenesGenerator.new, &block)
  generator.upper_bound = ubound
  generator.each(&block)
end
int_from_prime_division(pd) click to toggle source

Re-composes a prime factorization and returns the product.

Parameters

pd

Array of pairs of integers. The each internal pair consists of a prime number – a prime factor – and a natural number – an exponent.

Example

For [[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]], it returns:

p_1**e_1 * p_2**e_2 * .... * p_n**e_n.

Prime.int_from_prime_division([[2,2], [3,1]])  #=> 12

# File lib/prime.rb, line 182
def int_from_prime_division(pd)
  pd.inject(1){|value, (prime, index)|
    value *= prime**index
  }
end
prime?(value, generator = Prime::Generator23.new) click to toggle source

Returns true if value is prime, false for a composite.

Parameters

value

an arbitrary integer to be checked.

generator

optional. A pseudo-prime generator.

# File lib/prime.rb, line 159
def prime?(value, generator = Prime::Generator23.new)
  value = -value if value < 0
  return false if value < 2
  for num in generator
    q,r = value.divmod num
    return true if q < num
    return false if r == 0
  end
end
prime_division(value, generator= Prime::Generator23.new) click to toggle source

Returns the factorization of value.

Parameters

value

An arbitrary integer.

generator

Optional. A pseudo-prime generator. generator.succ must return the next pseudo-prime number in the ascendent order. It must generate all prime numbers, but may generate non prime numbers.

Exceptions

ZeroDivisionError

when value is zero.

Example

For an arbitrary integer:

n = p_1**e_1 * p_2**e_2 * .... * p_n**e_n,

#prime_division(n) returns:

[[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]].

Prime.prime_division(12) #=> [[2,2], [3,1]]

# File lib/prime.rb, line 212
def prime_division(value, generator= Prime::Generator23.new)
  raise ZeroDivisionError if value == 0
  if value < 0
    value = -value
    pv = [[-1, 1]]
  else
    pv = []
  end
  for prime in generator
    count = 0
    while (value1, mod = value.divmod(prime)
           mod) == 0
      value = value1
      count += 1
    end
    if count != 0
      pv.push [prime, count]
    end
    break if value1 <= prime
  end
  if value > 1
    pv.push [value, 1]
  end
  return pv
end


class Prime::EratosthenesGenerator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Prime::EratosthenesGenerator

An implementation of PseudoPrimeGenerator.

Uses EratosthenesSieve.

In Files

  • lib/prime.rb

Parent

Prime::PseudoPrimeGenerator

Public Class Methods

new() click to toggle source
# File lib/prime.rb, line 308
def initialize
  @last_prime = nil
  super
end

Public Instance Methods

next() click to toggle source
Alias for: succ
rewind() click to toggle source
# File lib/prime.rb, line 316
def rewind
  initialize
end
succ() click to toggle source
# File lib/prime.rb, line 313
def succ
  @last_prime = @last_prime ? EratosthenesSieve.instance.next_to(@last_prime) : 2
end
Also aliased as: next


class Prime::EratosthenesSieve - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Prime::EratosthenesSieve

Internal use. An implementation of eratosthenes's sieve

In Files

  • lib/prime.rb

Parent

Object

Included Modules

  • Singleton

Constants

BITS_PER_ENTRY
ENTRIES_PER_TABLE
FILLED_ENTRY
NUMS_PER_ENTRY
NUMS_PER_TABLE

Public Instance Methods

next_to(n) click to toggle source

returns the least odd prime number which is greater than n.

# File lib/prime.rb, line 441
def next_to(n)
  n = (n-1).div(2)*2+3 # the next odd number to given n
  table_index, integer_index, bit_index = indices(n)
  loop do
    extend_table until @tables.length > table_index
    for j in integer_index...ENTRIES_PER_TABLE
      if !@tables[table_index][j].zero?
        for k in bit_index...BITS_PER_ENTRY
          return NUMS_PER_TABLE*table_index + NUMS_PER_ENTRY*j + 2*k+1 if !@tables[table_index][j][k].zero?
        end
      end
      bit_index = 0
    end
    table_index += 1; integer_index = 0
  end
end


class Prime::Generator23 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Prime::Generator23

Generates all integer which are greater than 2 and are not divided by 2 nor 3.

This is a pseudo-prime generator, suitable on checking primality of a integer by brute force method.

In Files

  • lib/prime.rb

Parent

Prime::PseudoPrimeGenerator

Public Class Methods

new() click to toggle source
# File lib/prime.rb, line 346
def initialize
  @prime = 1
  @step = nil
  super
end

Public Instance Methods

next() click to toggle source
Alias for: succ
rewind() click to toggle source
# File lib/prime.rb, line 368
def rewind
  initialize
end
succ() click to toggle source
# File lib/prime.rb, line 352
def succ
  loop do
    if (@step)
      @prime += @step
      @step = 6 - @step
    else
      case @prime
      when 1; @prime = 2
      when 2; @prime = 3
      when 3; @prime = 5; @step = 2
      end
    end
    return @prime
  end
end
Also aliased as: next


module Prime::OldCompatibility - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Prime::OldCompatibility

Provides a Prime object with compatibility to Ruby 1.8 when instantiated via Prime.new.

In Files

  • lib/prime.rb

Public Instance Methods

each() { |succ| ... } click to toggle source

Overwrites Prime#each.

Iterates the given block over all prime numbers. Note that enumeration starts from the current position of internal pointer, not rewound.

# File lib/prime.rb, line 502
def each(&block)
  return @generator.dup unless block_given?
  loop do
    yield succ
  end
end
next() click to toggle source
Alias for: succ
succ() click to toggle source

Returns the next prime number and forwards internal pointer.

# File lib/prime.rb, line 493
def succ
  @generator.succ
end
Also aliased as: next


class Prime::PseudoPrimeGenerator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Prime::PseudoPrimeGenerator

An abstract class for enumerating pseudo-prime numbers.

Concrete subclasses should override succ, next, rewind.

In Files

  • lib/prime.rb

Parent

Object

Included Modules

  • Enumerable

Public Class Methods

new(ubound = nil) click to toggle source
# File lib/prime.rb, line 244
def initialize(ubound = nil)
  @ubound = ubound
end

Public Instance Methods

each(&block) click to toggle source

Iterates the given block for each prime numbers.

# File lib/prime.rb, line 276
def each(&block)
  return self.dup unless block
  if @ubound
    last_value = nil
    loop do
      prime = succ
      break last_value if prime > @ubound
      last_value = block.call(prime)
    end
  else
    loop do
      block.call(succ)
    end
  end
end
next() click to toggle source

alias of succ.

# File lib/prime.rb, line 264
def next
  raise NotImplementedError, "need to define `next'"
end
rewind() click to toggle source

Rewinds the internal position for enumeration.

See Enumerator rewind.

# File lib/prime.rb, line 271
def rewind
  raise NotImplementedError, "need to define `rewind'"
end
succ() click to toggle source

returns the next pseudo-prime number, and move the internal position forward.

PseudoPrimeGenerator succ raises NotImplementedError.

# File lib/prime.rb, line 259
def succ
  raise NotImplementedError, "need to define `succ'"
end
upper_bound() click to toggle source
# File lib/prime.rb, line 251
def upper_bound
  @ubound
end
upper_bound=(ubound) click to toggle source
# File lib/prime.rb, line 248
def upper_bound=(ubound)
  @ubound = ubound
end
with_object(obj) { |prime, obj| ... } click to toggle source

see Enumerator with_object.

# File lib/prime.rb, line 296
def with_object(obj)
  return enum_for(:with_object) unless block_given?
  each do |prime|
    yield prime, obj
  end
end


class Prime::TrialDivision - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Prime::TrialDivision

Internal use. An implementation of prime table by trial division method.

In Files

  • lib/prime.rb

Parent

Object

Included Modules

  • Singleton

Public Instance Methods

[](index) click to toggle source

Returns the +index+th prime number.

index is a 0-based index.

# File lib/prime.rb, line 400
def [](index)
  while index >= @primes.length
    # Only check for prime factors up to the square root of the potential primes,
    #   but without the performance hit of an actual square root calculation.
    if @next_to_check + 4 > @ulticheck_next_squared
      @ulticheck_index += 1
      @ulticheck_next_squared = @primes.at(@ulticheck_index + 1) ** 2
    end
    # Only check numbers congruent to one and five, modulo six. All others

    #   are divisible by two or three.  This also allows us to skip checking against
    #   two and three.
    @primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?
    @next_to_check += 4
    @primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?
    @next_to_check += 2
  end
  return @primes[index]
end
cache() click to toggle source

Returns the cached prime numbers.

# File lib/prime.rb, line 391
def cache
  return @primes
end
Also aliased as: primes, primes_so_far
primes() click to toggle source
Alias for: cache
primes_so_far() click to toggle source
Alias for: cache


class Prime::TrialDivisionGenerator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Prime::TrialDivisionGenerator

An implementation of PseudoPrimeGenerator which uses a prime table generated by trial division.

In Files

  • lib/prime.rb

Parent

Prime::PseudoPrimeGenerator

Public Class Methods

new() click to toggle source
# File lib/prime.rb, line 325
def initialize
  @index = -1
  super
end

Public Instance Methods

next() click to toggle source
Alias for: succ
rewind() click to toggle source
# File lib/prime.rb, line 333
def rewind
  initialize
end
succ() click to toggle source
# File lib/prime.rb, line 330
def succ
  TrialDivision.instance[@index += 1]
end
Also aliased as: next


module Profiler__ - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Profiler__

Profile provides a way to Profile your Ruby application.

Profiling your program is a way of determining which methods are called and how long each method takes to complete. This way you can detect which methods are possible bottlenecks.

Profiling your program will slow down your execution time considerably, so activate it only when you need it. Don't confuse benchmarking with profiling.

There are two ways to activate Profiling:

Command line

Run your Ruby script with -rprofile:

ruby -rprofile example.rb

If you're profiling an executable in your $PATH you can use ruby -S:

ruby -rprofile -S some_executable

From code

Just require 'profile':

require 'profile'

def slow_method
  5000.times do
    9999999999999999*999999999
  end
end

def fast_method
  5000.times do
    9999999999999999+999999999
  end
end

slow_method
fast_method

The output in both cases is a report when the execution is over:

ruby -rprofile example.rb

  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 68.42     0.13      0.13        2    65.00    95.00  Integer#times
 15.79     0.16      0.03     5000     0.01     0.01  Fixnum#*
 15.79     0.19      0.03     5000     0.01     0.01  Fixnum#+
  0.00     0.19      0.00        2     0.00     0.00  IO#set_encoding
  0.00     0.19      0.00        1     0.00   100.00  Object#slow_method
  0.00     0.19      0.00        2     0.00     0.00  Module#method_added
  0.00     0.19      0.00        1     0.00    90.00  Object#fast_method
  0.00     0.19      0.00        1     0.00   190.00  #toplevel

In Files

  • lib/profiler.rb

Public Instance Methods

print_profile(f) click to toggle source
# File lib/profiler.rb, line 110
def print_profile(f)
  stop_profile
  total = Process.times[0] - @@start
  if total == 0 then total = 0.01 end
  totals = {}
  @@maps.values.each do |threadmap|
    threadmap.each do |key, data|
      total_data = (totals[key] ||= [0, 0.0, 0.0, key])
      total_data[0] += data[0]
      total_data[1] += data[1]
      total_data[2] += data[2]
    end
  end

  # Maybe we should show a per thread output and a totals view?

  data = totals.values
  data = data.sort_by{|x| -x[2]}
  sum = 0
  f.printf "  %%   cumulative   self              self     total\n"
  f.printf " time   seconds   seconds    calls  ms/call  ms/call  name\n"
  for d in data
    sum += d[2]
    f.printf "%6.2f %8.2f  %8.2f %8d ", d[2]/total*100, sum, d[2], d[0]
    f.printf "%8.2f %8.2f  %s\n", d[2]*1000/d[0], d[1]*1000/d[0], d[3]
  end
  f.printf "%6.2f %8.2f  %8.2f %8d ", 0.0, total, 0.0, 1     # ???
  f.printf "%8.2f %8.2f  %s\n", 0.0, total*1000, "#toplevel" # ???
end
start_profile() click to toggle source
# File lib/profiler.rb, line 99
def start_profile
  @@start = Process.times[0]
  @@stacks = {}
  @@maps = {}
  PROFILE_CALL_PROC.enable
  PROFILE_RETURN_PROC.enable
end
stop_profile() click to toggle source
# File lib/profiler.rb, line 106
def stop_profile
  PROFILE_CALL_PROC.disable
  PROFILE_RETURN_PROC.disable
end


module Psych - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Psych

This exists just to satify bugs in marshal'd gemspecs that contain a reference to YAML::PrivateType. We prune these out in Specification._load, but if we don't have the constant, Marshal blows up.

Overview

Psych is a YAML parser and emitter. Psych leverages libyaml [Home page: pyyaml.org/wiki/LibYAML] or [Git repo: github.com/zerotao/libyaml] for its YAML parsing and emitting capabilities. In addition to wrapping libyaml, Psych also knows how to serialize and de-serialize most Ruby objects to and from the YAML format.

I NEED TO PARSE OR EMIT YAML RIGHT NOW!

# Parse some YAML
Psych.load("--- foo") # => "foo"

# Emit some YAML
Psych.dump("foo")     # => "--- foo\n...\n"
{ :a => 'b'}.to_yaml  # => "---\n:a: b\n"

Got more time on your hands? Keep on reading!

YAML Parsing

Psych provides a range of interfaces for parsing a YAML document ranging from low level to high level, depending on your parsing needs. At the lowest level, is an event based parser. Mid level is access to the raw YAML AST, and at the highest level is the ability to unmarshal YAML to ruby objects.

Low level parsing

The lowest level parser should be used when the YAML input is already known, and the developer does not want to pay the price of building an AST or automatic detection and conversion to ruby objects. See Psych::Parser for more information on using the event based parser.

Mid level parsing

Psych provides access to an AST produced from parsing a YAML document. This tree is built using the Psych::Parser and Psych::TreeBuilder. The AST can be examined and manipulated freely. Please see ::parse_stream, Psych::Nodes, and Psych::Nodes::Node for more information on dealing with YAML syntax trees.

High level parsing

The high level YAML parser provided by Psych simply takes YAML as input and returns a Ruby data structure. For information on using the high level parser see ::load

YAML Emitting

Psych provides a range of interfaces ranging from low to high level for producing YAML documents. Very similar to the YAML parsing interfaces, Psych provides at the lowest level, an event based system, mid-level is building a YAML AST, and the highest level is converting a Ruby object straight to a YAML document.

Low level emitting

The lowest level emitter is an event based system. Events are sent to a Psych::Emitter object. That object knows how to convert the events to a YAML document. This interface should be used when document format is known in advance or speed is a concern. See Psych::Emitter for more information.

Mid level emitting

At the mid level is building an AST. This AST is exactly the same as the AST used when parsing a YAML document. Users can build an AST by hand and the AST knows how to emit itself as a YAML document. See Psych::Nodes, Psych::Nodes::Node, and Psych::TreeBuilder for more information on building a YAML AST.

High level emitting

The high level emitter has the easiest interface. Psych simply takes a Ruby data structure and converts it to a YAML document. See ::dump for more information on dumping a Ruby data structure.

In Files

  • lib/rubygems/psych_additions.rb
  • lib/yaml.rb
  • ext/psych/lib/psych/coder.rb
  • ext/psych/lib/psych/deprecated.rb
  • ext/psych/lib/psych/handler.rb
  • ext/psych/lib/psych/handlers/document_stream.rb
  • ext/psych/lib/psych/handlers/recorder.rb
  • ext/psych/lib/psych/json/ruby_events.rb
  • ext/psych/lib/psych/json/stream.rb
  • ext/psych/lib/psych/json/tree_builder.rb
  • ext/psych/lib/psych/json/yaml_events.rb
  • ext/psych/lib/psych/nodes/alias.rb
  • ext/psych/lib/psych/nodes/document.rb
  • ext/psych/lib/psych/nodes/mapping.rb
  • ext/psych/lib/psych/nodes/node.rb
  • ext/psych/lib/psych/nodes/scalar.rb
  • ext/psych/lib/psych/nodes/sequence.rb
  • ext/psych/lib/psych/nodes/stream.rb
  • ext/psych/lib/psych/nodes.rb
  • ext/psych/lib/psych/omap.rb
  • ext/psych/lib/psych/parser.rb
  • ext/psych/lib/psych/scalar_scanner.rb
  • ext/psych/lib/psych/set.rb
  • ext/psych/lib/psych/stream.rb
  • ext/psych/lib/psych/streaming.rb
  • ext/psych/lib/psych/syntax_error.rb
  • ext/psych/lib/psych/tree_builder.rb
  • ext/psych/lib/psych/visitors/depth_first.rb
  • ext/psych/lib/psych/visitors/emitter.rb
  • ext/psych/lib/psych/visitors/json_tree.rb
  • ext/psych/lib/psych/visitors/to_ruby.rb
  • ext/psych/lib/psych/visitors/visitor.rb
  • ext/psych/lib/psych/visitors/yaml_tree.rb
  • ext/psych/lib/psych.rb
  • ext/psych/psych.c

Constants

LIBYAML_VERSION

The version of libyaml Psych is using

VERSION

The version is Psych you're using

Public Class Methods

add_private_type(type_tag, &block) click to toggle source
# File ext/psych/lib/psych/deprecated.rb, line 48
def self.add_private_type type_tag, &block
  warn "#{caller[0]}: add_private_type is deprecated, use add_domain_type" if $VERBOSE
  domain = 'x-private'
  key = [domain, type_tag].join ':'
  @domain_types[key] = [key, block]
end
add_ruby_type(type_tag, &block) click to toggle source
# File ext/psych/lib/psych/deprecated.rb, line 41
def self.add_ruby_type type_tag, &block
  warn "#{caller[0]}: add_ruby_type is deprecated, use add_domain_type" if $VERBOSE
  domain = 'ruby.yaml.org,2002'
  key = ['tag', domain, type_tag].join ':'
  @domain_types[key] = [key, block]
end
detect_implicit(thing) click to toggle source
# File ext/psych/lib/psych/deprecated.rb, line 34
def self.detect_implicit thing
  warn "#{caller[0]}: detect_implicit is deprecated" if $VERBOSE
  return '' unless String === thing
  return 'null' if '' == thing
  ScalarScanner.new.tokenize(thing).class.name.downcase
end
dump(o) → string of yaml click to toggle source
dump(o, options) → string of yaml
dump(o, io) → io object passed in
dump(o, io, options) → io object passed in

Dump Ruby object o to a YAML string. Optional options may be passed in to control the output format. If an IO object is passed in, the YAML will be dumped to that IO object.

Example:

# Dump an array, get back a YAML string
Psych.dump(['a', 'b'])  # => "---\n- a\n- b\n"

# Dump an array to an IO object
Psych.dump(['a', 'b'], StringIO.new)  # => #<StringIO:0x000001009d0890>

# Dump an array with indentation set
Psych.dump(['a', ['b']], :indentation => 3) # => "---\n- a\n-  - b\n"

# Dump an array to an IO with indentation set
Psych.dump(['a', ['b']], StringIO.new, :indentation => 3)

# File ext/psych/lib/psych.rb, line 237
def self.dump o, io = nil, options = {}
  if Hash === io
    options = io
    io      = nil
  end

  visitor = Psych::Visitors::YAMLTree.new options
  visitor << o
  visitor.tree.yaml io, options
end
dump_stream(*objects) click to toggle source

Dump a list of objects as separate documents to a document stream.

Example:

Psych.dump_stream("foo\n  ", {}) # => "--- ! \"foo\\n  \"\n--- {}\n"

# File ext/psych/lib/psych.rb, line 254
def self.dump_stream *objects
  visitor = Psych::Visitors::YAMLTree.new {}
  objects.each do |o|
    visitor << o
  end
  visitor.tree.yaml
end
libyaml_version click to toggle source

Returns the version of libyaml being used

static VALUE libyaml_version(VALUE module)
{
    int major, minor, patch;
    VALUE list[3];

    yaml_get_version(&major, &minor, &patch);

    list[0] = INT2NUM((long)major);
    list[1] = INT2NUM((long)minor);
    list[2] = INT2NUM((long)patch);

    return rb_ary_new4((long)3, list);
}
load(yaml, filename = nil) click to toggle source

Load yaml in to a Ruby data structure. If multiple documents are provided, the object contained in the first document will be returned. filename will be used in the exception message if any exception is raised while parsing.

Raises a Psych::SyntaxError when a YAML syntax error is detected.

Example:

Psych.load("--- a")             # => 'a'
Psych.load("---\n - a\n - b")   # => ['a', 'b']

begin
  Psych.load("--- `", "file.txt")
rescue Psych::SyntaxError => ex
  ex.file    # => 'file.txt'
  ex.message # => "(file.txt): found character that cannot start any token"
end

# File ext/psych/lib/psych.rb, line 128
def self.load yaml, filename = nil
  result = parse(yaml, filename)
  result ? result.to_ruby : result
end
load_documents(yaml, &block) click to toggle source

This method is deprecated, use ::load_stream instead.

# File ext/psych/lib/psych/deprecated.rb, line 25
def self.load_documents yaml, &block
  if $VERBOSE
    warn "#{caller[0]}: load_documents is deprecated, use load_stream"
  end
  list = load_stream yaml
  return list unless block_given?
  list.each(&block)
end
load_file(filename) click to toggle source

Load the document contained in filename. Returns the yaml contained in filename as a ruby object

# File ext/psych/lib/psych.rb, line 298
def self.load_file filename
  File.open(filename, 'r:bom|utf-8') { |f| self.load f, filename }
end
load_stream(yaml, filename = nil) { |to_ruby| ... } click to toggle source

Load multiple documents given in yaml. Returns the parsed documents as a list. If a block is given, each document will be converted to ruby and passed to the block during parsing

Example:

Psych.load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar']

list = []
Psych.load_stream("--- foo\n...\n--- bar\n...") do |ruby|
  list << ruby
end
list # => ['foo', 'bar']

# File ext/psych/lib/psych.rb, line 285
def self.load_stream yaml, filename = nil
  if block_given?
    parse_stream(yaml, filename) do |node|
      yield node.to_ruby
    end
  else
    parse_stream(yaml, filename).children.map { |child| child.to_ruby }
  end
end
object_maker(klass, hash) click to toggle source
# File ext/psych/lib/psych/deprecated.rb, line 71
def self.object_maker klass, hash
  warn "#{caller[0]}: object_maker is deprecated" if $VERBOSE
  klass.allocate.tap do |obj|
    hash.each { |k,v| obj.instance_variable_set(:"@#{k}", v) }
  end
end
parse(yaml, filename = nil) click to toggle source

Parse a YAML string in yaml. Returns the first object of a YAML AST. filename is used in the exception message if a Psych::SyntaxError is raised.

Raises a Psych::SyntaxError when a YAML syntax error is detected.

Example:

Psych.parse("---\n - a\n - b") # => #<Psych::Nodes::Sequence:0x00>

begin
  Psych.parse("--- `", "file.txt")
rescue Psych::SyntaxError => ex
  ex.file    # => 'file.txt'
  ex.message # => "(file.txt): found character that cannot start any token"
end

See Psych::Nodes for more information about YAML AST.

# File ext/psych/lib/psych.rb, line 152
def self.parse yaml, filename = nil
  parse_stream(yaml, filename) do |node|
    return node
  end
  false
end
parse_file(filename) click to toggle source

Parse a file at filename. Returns the YAML AST.

Raises a Psych::SyntaxError when a YAML syntax error is detected.

# File ext/psych/lib/psych.rb, line 163
def self.parse_file filename
  File.open filename, 'r:bom|utf-8' do |f|
    parse f, filename
  end
end
parse_stream(yaml, filename = nil, &block) click to toggle source

Parse a YAML string in yaml. Returns the full AST for the YAML document. This method can handle multiple YAML documents contained in yaml. filename is used in the exception message if a Psych::SyntaxError is raised.

If a block is given, a Psych::Nodes::Document node will be yielded to the block as it's being parsed.

Raises a Psych::SyntaxError when a YAML syntax error is detected.

Example:

Psych.parse_stream("---\n - a\n - b") # => #<Psych::Nodes::Stream:0x00>

Psych.parse_stream("--- a\n--- b") do |node|
  node # => #<Psych::Nodes::Document:0x00>
end

begin
  Psych.parse_stream("--- `", "file.txt")
rescue Psych::SyntaxError => ex
  ex.file    # => 'file.txt'
  ex.message # => "(file.txt): found character that cannot start any token"
end

See Psych::Nodes for more information about YAML AST.

# File ext/psych/lib/psych.rb, line 202
def self.parse_stream yaml, filename = nil, &block
  if block_given?
    parser = Psych::Parser.new(Handlers::DocumentStream.new(&block))
    parser.parse yaml, filename
  else
    parser = self.parser
    parser.parse yaml, filename
    parser.handler.root
  end
end
parser() click to toggle source

Returns a default parser

# File ext/psych/lib/psych.rb, line 171
def self.parser
  Psych::Parser.new(TreeBuilder.new)
end
quick_emit(thing, opts = {}) click to toggle source
# File ext/psych/lib/psych/deprecated.rb, line 11
def self.quick_emit thing, opts = {}, &block # :nodoc:
  warn "#{caller[0]}: YAML.quick_emit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
  target = eval 'self', block.binding
  target.extend DeprecatedMethods
  metaclass = class << target; self; end
  metaclass.send(:define_method, :encode_with) do |coder|
    target.taguri        = coder.tag
    target.to_yaml_style = coder.style
    block.call coder
  end
  target.psych_to_yaml unless opts[:nodump]
end
read_type_class(type, reference) click to toggle source
# File ext/psych/lib/psych/deprecated.rb, line 61
def self.read_type_class type, reference
  warn "#{caller[0]}: read_type_class is deprecated" if $VERBOSE
  _, _, type, name = type.split ':', 4

  reference = name.split('::').inject(reference) do |k,n|
    k.const_get(n.to_sym)
  end if name
  [type, reference]
end
tagurize(thing) click to toggle source
# File ext/psych/lib/psych/deprecated.rb, line 55
def self.tagurize thing
  warn "#{caller[0]}: add_private_type is deprecated, use add_domain_type" if $VERBOSE
  return thing unless String === thing
  "tag:yaml.org,2002:#{thing}"
end
to_json(o) click to toggle source

Dump Ruby object o to a JSON string.

# File ext/psych/lib/psych.rb, line 264
def self.to_json o
  visitor = Psych::Visitors::JSONTree.new
  visitor << o
  visitor.tree.yaml
end


class Psych::BadAlias - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::BadAlias

In Files

  • ext/psych/lib/psych.rb

Parent

Psych::Exception


class Psych::Coder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Coder

If an object defines encode_with, then an instance of Psych::Coder will be passed to the method when the object is being serialized. The Coder automatically assumes a Psych::Nodes::Mapping is being emitted. Other objects like Sequence and Scalar may be emitted if seq= or scalar= are called, respectively.

In Files

  • ext/psych/lib/psych/coder.rb

Parent

Object

Attributes

implicit[RW]
object[RW]
seq[R]
style[RW]
tag[RW]
type[R]

Public Class Methods

new(tag) click to toggle source
# File ext/psych/lib/psych/coder.rb, line 12
def initialize tag
  @map      = {}
  @seq      = []
  @implicit = false
  @type     = :map
  @tag      = tag
  @style    = Psych::Nodes::Mapping::BLOCK
  @scalar   = nil
  @object   = nil
end

Public Instance Methods

[](k) click to toggle source
# File ext/psych/lib/psych/coder.rb, line 83
def [] k
  @type = :map
  @map[k]
end
[]=(k, v) click to toggle source
# File ext/psych/lib/psych/coder.rb, line 77
def []= k, v
  @type = :map
  @map[k] = v
end
Also aliased as: add
add(k, v) click to toggle source
Alias for: []=
map(tag = @tag, style = @style) { |self| ... } click to toggle source

Emit a map. The coder will be yielded to the block.

# File ext/psych/lib/psych/coder.rb, line 33
def map tag = @tag, style = @style
  @tag   = tag
  @style = style
  yield self if block_given?
  @map
end
map=(map) click to toggle source

Emit a map with value

# File ext/psych/lib/psych/coder.rb, line 72
def map= map
  @type = :map
  @map  = map
end
represent_map(tag, map) click to toggle source

Emit a sequence with map and tag

# File ext/psych/lib/psych/coder.rb, line 53
def represent_map tag, map
  @tag = tag
  self.map = map
end
represent_object(tag, obj) click to toggle source

Emit an arbitrary object obj and tag

# File ext/psych/lib/psych/coder.rb, line 59
def represent_object tag, obj
  @tag    = tag
  @type   = :object
  @object = obj
end
represent_scalar(tag, value) click to toggle source

Emit a scalar with value and tag

# File ext/psych/lib/psych/coder.rb, line 41
def represent_scalar tag, value
  self.tag    = tag
  self.scalar = value
end
represent_seq(tag, list) click to toggle source

Emit a sequence with list and tag

# File ext/psych/lib/psych/coder.rb, line 47
def represent_seq tag, list
  @tag = tag
  self.seq = list
end
scalar(*args) click to toggle source
# File ext/psych/lib/psych/coder.rb, line 23
def scalar *args
  if args.length > 0
    warn "#{caller[0]}: Coder#scalar(a,b,c) is deprecated" if $VERBOSE
    @tag, @scalar, _ = args
    @type = :scalar
  end
  @scalar
end
scalar=(value) click to toggle source

Emit a scalar with value

# File ext/psych/lib/psych/coder.rb, line 66
def scalar= value
  @type   = :scalar
  @scalar = value
end
seq=(list) click to toggle source

Emit a sequence of list

# File ext/psych/lib/psych/coder.rb, line 89
def seq= list
  @type = :seq
  @seq  = list
end


class Psych::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Error

In Files

  • ext/psych/lib/psych/syntax_error.rb

Parent

RuntimeError


class Psych::Exception - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Exception

In Files

  • ext/psych/lib/psych.rb

Parent

RuntimeError


class Psych::Handler - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Handler

Psych::Handler is an abstract base class that defines the events used when dealing with Psych::Parser. Clients who want to use Psych::Parser should implement a class that inherits from Psych::Handler and define events that they can handle.

Psych::Handler defines all events that Psych::Parser can possibly send to event handlers.

See Psych::Parser for more details

In Files

  • ext/psych/lib/psych/handler.rb

Parent

Object

Constants

EVENTS

Events that a Handler should respond to.

OPTIONS

Default dumping options

Public Instance Methods

alias(anchor) click to toggle source

Called when an alias is found to anchor. anchor will be the name of the anchor found.

Example

Here we have an example of an array that references itself in YAML:

--- &ponies
- first element
- *ponies

&ponies is the achor, *ponies is the alias. In this case, alias is called with “ponies”.

# File ext/psych/lib/psych/handler.rb, line 109
def alias anchor
end
empty() click to toggle source

Called when an empty event happens. (Which, as far as I can tell, is never).

# File ext/psych/lib/psych/handler.rb, line 235
def empty
end
end_document(implicit) click to toggle source

Called with the document ends. implicit is a boolean value indicating whether or not the document has an implicit ending.

Example

Given the following YAML:

---
  hello world

implicit will be true. Given this YAML:

---
  hello world
...

implicit will be false.

# File ext/psych/lib/psych/handler.rb, line 92
def end_document implicit
end
end_mapping() click to toggle source

Called when a map ends

# File ext/psych/lib/psych/handler.rb, line 229
def end_mapping
end
end_sequence() click to toggle source

Called when a sequence ends.

# File ext/psych/lib/psych/handler.rb, line 190
def end_sequence
end
end_stream() click to toggle source

Called when the YAML stream ends

# File ext/psych/lib/psych/handler.rb, line 240
def end_stream
end
scalar(value, anchor, tag, plain, quoted, style) click to toggle source

Called when a scalar value is found. The scalar may have an anchor, a tag, be implicitly plain or implicitly quoted

value is the string value of the scalar anchor is an associated anchor or nil tag is an associated tag or nil plain is a boolean value quoted is a boolean value style is an integer idicating the string style

See the constants in Psych::Nodes::Scalar for the possible values of style

Example

Here is a YAML document that exercises most of the possible ways this method can be called:

---
- !str "foo"
- &anchor fun
- many
  lines
- |
  many
  newlines

The above YAML document contains a list with four strings. Here are the parameters sent to this method in the same order:

# value               anchor    tag     plain   quoted  style
["foo",               nil,      "!str", false,  false,  3    ]
["fun",               "anchor", nil,    true,   false,  1    ]
["many lines",        nil,      nil,    true,   false,  1    ]
["many\nnewlines\n",  nil,      nil,    false,  true,   4    ]
# File ext/psych/lib/psych/handler.rb, line 149
def scalar value, anchor, tag, plain, quoted, style
end
start_document(version, tag_directives, implicit) click to toggle source

Called when the document starts with the declared version, tag_directives, if the document is implicit.

version will be an array of integers indicating the YAML version being dealt with, tag_directives is a list of tuples indicating the prefix and suffix of each tag, and implicit is a boolean indicating whether the document is started implicitly.

Example

Given the following YAML:

%YAML 1.1
%TAG ! tag:tenderlovemaking.com,2009:
--- !squee

The parameters for #start_document must be this:

version         # => [1, 1]
tag_directives  # => [["!", "tag:tenderlovemaking.com,2009:"]]
implicit        # => false

# File ext/psych/lib/psych/handler.rb, line 71
def start_document version, tag_directives, implicit
end
start_mapping(anchor, tag, implicit, style) click to toggle source

Called when a map starts.

anchor is the anchor associated with the map or nil. tag is the tag associated with the map or nil. implicit is a boolean indicating whether or not the map was implicitly started. style is an integer indicating the mapping style.

See the constants in Psych::Nodes::Mapping for the possible values of style.

Example

Here is a YAML document that exercises most of the possible ways this method can be called:

---
k: !!map { hello: world }
v: &pewpew
  hello: world

The above YAML document consists of three maps, an outer map that contains two inner maps. Below is a matrix of the parameters sent in order to represent these three maps:

# anchor    tag                       implicit  style
[nil,       nil,                      true,     1     ]
[nil,       "tag:yaml.org,2002:map",  false,    2     ]
["pewpew",  nil,                      true,     1     ]
# File ext/psych/lib/psych/handler.rb, line 224
def start_mapping anchor, tag, implicit, style
end
start_sequence(anchor, tag, implicit, style) click to toggle source

Called when a sequence is started.

anchor is the anchor associated with the sequence or nil. tag is the tag associated with the sequence or nil. implicit a boolean indicating whether or not the sequence was implicitly started. style is an integer indicating the list style.

See the constants in Psych::Nodes::Sequence for the possible values of style.

Example

Here is a YAML document that exercises most of the possible ways this method can be called:

---
- !!seq [
  a
]
- &pewpew
  - b

The above YAML document consists of three lists, an outer list that contains two inner lists. Here is a matrix of the parameters sent to represent these lists:

# anchor    tag                       implicit  style
[nil,       nil,                      true,     1     ]
[nil,       "tag:yaml.org,2002:seq",  false,    2     ]
["pewpew",  nil,                      true,     1     ]
# File ext/psych/lib/psych/handler.rb, line 185
def start_sequence anchor, tag, implicit, style
end
start_stream(encoding) click to toggle source

Called with encoding when the YAML stream starts. This method is called once per stream. A stream may contain multiple documents.

See the constants in Psych::Parser for the possible values of encoding.

# File ext/psych/lib/psych/handler.rb, line 46
def start_stream encoding
end
streaming?() click to toggle source

Is this handler a streaming handler?

# File ext/psych/lib/psych/handler.rb, line 245
def streaming?
  false
end


class Psych::Handler::DumperOptions - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Handler::DumperOptions

Configuration options for dumping YAML.

In Files

  • ext/psych/lib/psych/handler.rb

Parent

Object

Attributes

canonical[RW]
indentation[RW]
line_width[RW]

Public Class Methods

new() click to toggle source
# File ext/psych/lib/psych/handler.rb, line 18
def initialize
  @line_width  = 0
  @indentation = 2
  @canonical   = false
end


module Psych::Handlers - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Psych::Handlers

In Files

  • ext/psych/lib/psych/handlers/document_stream.rb
  • ext/psych/lib/psych/handlers/recorder.rb


class Psych::Handlers::Recorder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Handlers::Recorder

This handler will capture an event and record the event. Recorder events are available vial #events.

For example:

recorder = Psych::Handlers::Recorder.new
parser = Psych::Parser.new recorder
parser.parse '--- foo'

recorder.events # => [list of events]

# Replay the events

emitter = Psych::Emitter.new $stdout
recorder.events.each do |m, args|
  emitter.send m, *args
end

In Files

  • ext/psych/lib/psych/handlers/recorder.rb

Parent

Psych::Handler

Attributes

events[R]

Public Class Methods

new() click to toggle source
# File ext/psych/lib/psych/handlers/recorder.rb, line 27
def initialize
  @events = []
  super
end


module Psych::JSON - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Psych::JSON

In Files

  • ext/psych/lib/psych/json/ruby_events.rb
  • ext/psych/lib/psych/json/stream.rb
  • ext/psych/lib/psych/json/tree_builder.rb
  • ext/psych/lib/psych/json/yaml_events.rb


class Psych::JSON::Stream - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::JSON::Stream

In Files

  • ext/psych/lib/psych/json/stream.rb

Parent

Psych::Visitors::JSONTree

Included Modules

  • Psych::Streaming


class Psych::JSON::TreeBuilder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::JSON::TreeBuilder

Psych::JSON::TreeBuilder is an event based AST builder. Events are sent to an instance of Psych::JSON::TreeBuilder and a JSON AST is constructed.

In Files

  • ext/psych/lib/psych/json/tree_builder.rb

Parent

Psych::TreeBuilder


module Psych::Nodes - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Psych::Nodes

Overview

When using Psych.load to deserialize a YAML document, the document is translated to an intermediary AST. That intermediary AST is then translated in to a Ruby object graph.

In the opposite direction, when using Psych.dump, the Ruby object graph is translated to an intermediary AST which is then converted to a YAML document.

Psych::Nodes contains all of the classes that make up the nodes of a YAML AST. You can manually build an AST and use one of the visitors (see Psych::Visitors) to convert that AST to either a YAML document or to a Ruby object graph.

Here is an example of building an AST that represents a list with one scalar:

# Create our nodes
stream = Psych::Nodes::Stream.new
doc    = Psych::Nodes::Document.new
seq    = Psych::Nodes::Sequence.new
scalar = Psych::Nodes::Scalar.new('foo')

# Build up our tree
stream.children << doc
doc.children    << seq
seq.children    << scalar

The stream is the root of the tree. We can then convert the tree to YAML:

stream.to_yaml => "---\n- foo\n"

Or convert it to Ruby:

stream.to_ruby => [["foo"]]

YAML AST Requirements

A valid YAML AST must have one Psych::Nodes::Stream at the root. A Psych::Nodes::Stream node must have 1 or more Psych::Nodes::Document nodes as children.

Psych::Nodes::Document nodes must have one and only one child. That child may be one of:

  • Psych::Nodes::Sequence

  • Psych::Nodes::Mapping

  • Psych::Nodes::Scalar

Psych::Nodes::Sequence and Psych::Nodes::Mapping nodes may have many children, but Psych::Nodes::Mapping nodes should have an even number of children.

All of these are valid children for Psych::Nodes::Sequence and Psych::Nodes::Mapping nodes:

  • Psych::Nodes::Sequence

  • Psych::Nodes::Mapping

  • Psych::Nodes::Scalar

  • Psych::Nodes::Alias

Psych::Nodes::Scalar and Psych::Nodes::Alias are both terminal nodes and should not have any children.

In Files

  • ext/psych/lib/psych/nodes/alias.rb
  • ext/psych/lib/psych/nodes/document.rb
  • ext/psych/lib/psych/nodes/mapping.rb
  • ext/psych/lib/psych/nodes/node.rb
  • ext/psych/lib/psych/nodes/scalar.rb
  • ext/psych/lib/psych/nodes/sequence.rb
  • ext/psych/lib/psych/nodes/stream.rb
  • ext/psych/lib/psych/nodes.rb


class Psych::Nodes::Alias - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Nodes::Alias

This class represents a YAML Alias. It points to an anchor.

A Psych::Nodes::Alias is a terminal node and may have no children.

In Files

  • ext/psych/lib/psych/nodes/alias.rb

Parent

Psych::Nodes::Node

Attributes

anchor[RW]

The anchor this alias links to

Public Class Methods

new(anchor) click to toggle source

Create a new Alias that points to an anchor

# File ext/psych/lib/psych/nodes/alias.rb, line 13
def initialize anchor
  @anchor = anchor
end


class Psych::Nodes::Document - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Nodes::Document

This represents a YAML Document. This node must be a child of Psych::Nodes::Stream. A Psych::Nodes::Document must have one child, and that child may be one of the following:

  • Psych::Nodes::Sequence

  • Psych::Nodes::Mapping

  • Psych::Nodes::Scalar

In Files

  • ext/psych/lib/psych/nodes/document.rb

Parent

Psych::Nodes::Node

Attributes

implicit[RW]

Was this document implicitly created?

implicit_end[RW]

Is the end of the document implicit?

tag_directives[RW]

A list of tag directives for this document

version[RW]

The version of the YAML document

Public Class Methods

new(version = [], tag_directives = [], implicit = false) click to toggle source

Create a new Psych::Nodes::Document object.

version is a list indicating the YAML version. tags_directives is a list of tag directive declarations implicit is a flag indicating whether the document will be implicitly started.

Example:

This creates a YAML document object that represents a YAML 1.1 document with one tag directive, and has an implicit start:

Psych::Nodes::Document.new(
  [1,1],
  [["!", "tag:tenderlovemaking.com,2009:"]],
  true
)

See Also

See also Psych::Handler#start_document

# File ext/psych/lib/psych/nodes/document.rb, line 44
def initialize version = [], tag_directives = [], implicit = false
  super()
  @version        = version
  @tag_directives = tag_directives
  @implicit       = implicit
  @implicit_end   = true
end

Public Instance Methods

root() click to toggle source

Returns the root node. A Document may only have one root node: yaml.org/spec/1.1/#id898031

# File ext/psych/lib/psych/nodes/document.rb, line 55
def root
  children.first
end


class Psych::Nodes::Mapping - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Nodes::Mapping

This class represents a YAML Mapping.

A Psych::Nodes::Mapping node may have 0 or more children, but must have an even number of children. Here are the valid children a Psych::Nodes::Mapping node may have:

  • Psych::Nodes::Sequence

  • Psych::Nodes::Mapping

  • Psych::Nodes::Scalar

  • Psych::Nodes::Alias

In Files

  • ext/psych/lib/psych/nodes/mapping.rb

Parent

Psych::Nodes::Node

Constants

ANY

Any Map Style

BLOCK

Block Map Style

FLOW

Flow Map Style

Attributes

anchor[RW]

The optional anchor for this mapping

implicit[RW]

Is this an implicit mapping?

style[RW]

The style of this mapping

tag[RW]

The optional tag for this mapping

Public Class Methods

new(anchor = nil, tag = nil, implicit = true, style = BLOCK) click to toggle source

Create a new Psych::Nodes::Mapping object.

anchor is the anchor associated with the map or nil. tag is the tag associated with the map or nil. implicit is a boolean indicating whether or not the map was implicitly started. style is an integer indicating the mapping style.

See Also

See also Psych::Handler#start_mapping

# File ext/psych/lib/psych/nodes/mapping.rb, line 47
def initialize anchor = nil, tag = nil, implicit = true, style = BLOCK
  super()
  @anchor   = anchor
  @tag      = tag
  @implicit = implicit
  @style    = style
end


class Psych::Nodes::Node - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Nodes::Node

The base class for any Node in a YAML parse tree. This class should never be instantiated.

In Files

  • ext/psych/lib/psych/nodes/node.rb

Parent

Object

Included Modules

  • Enumerable

Attributes

children[R]

The children of this node

tag[R]

An associated tag

Public Class Methods

new() click to toggle source

Create a new Psych::Nodes::Node

# File ext/psych/lib/psych/nodes/node.rb, line 18
def initialize
  @children = []
end

Public Instance Methods

each(&block) click to toggle source

Iterate over each node in the tree. Yields each node to block depth first.

# File ext/psych/lib/psych/nodes/node.rb, line 25
def each &block
  return enum_for :each unless block_given?
  Visitors::DepthFirst.new(block).accept self
end
to_ruby() click to toggle source

Convert this node to Ruby.

See also Psych::Visitors::ToRuby

# File ext/psych/lib/psych/nodes/node.rb, line 34
def to_ruby
  Visitors::ToRuby.new.accept self
end
Also aliased as: transform
to_yaml(io = nil, options = {}) click to toggle source
Alias for: yaml
transform() click to toggle source
Alias for: to_ruby
yaml(io = nil, options = {}) click to toggle source

Convert this node to YAML.

See also Psych::Visitors::Emitter

# File ext/psych/lib/psych/nodes/node.rb, line 43
def yaml io = nil, options = {}
  real_io = io || StringIO.new(''.encode('utf-8'))

  Visitors::Emitter.new(real_io, options).accept self
  return real_io.string unless io
  io
end
Also aliased as: to_yaml


class Psych::Nodes::Scalar - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Nodes::Scalar

This class represents a YAML Scalar.

This node type is a terminal node and should not have any children.

In Files

  • ext/psych/lib/psych/nodes/scalar.rb

Parent

Psych::Nodes::Node

Constants

ANY

Any style scalar, the emitter chooses

DOUBLE_QUOTED

Double quoted style

FOLDED

Folded style

LITERAL

Literal style

PLAIN

Plain scalar style

SINGLE_QUOTED

Single quoted style

Attributes

anchor[RW]

The anchor value (if there is one)

plain[RW]

Is this a plain scalar?

quoted[RW]

Is this scalar quoted?

style[RW]

The style of this scalar

tag[RW]

The tag value (if there is one)

value[RW]

The scalar value

Public Class Methods

new(value, anchor = nil, tag = nil, plain = true, quoted = false, style = ANY) click to toggle source

Create a new Psych::Nodes::Scalar object.

value is the string value of the scalar anchor is an associated anchor or nil tag is an associated tag or nil plain is a boolean value quoted is a boolean value style is an integer idicating the string style

See Also

See also Psych::Handler#scalar

# File ext/psych/lib/psych/nodes/scalar.rb, line 57
def initialize value, anchor = nil, tag = nil, plain = true, quoted = false, style = ANY
  @value  = value
  @anchor = anchor
  @tag    = tag
  @plain  = plain
  @quoted = quoted
  @style  = style
end


class Psych::Nodes::Sequence - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Nodes::Sequence

This class represents a YAML sequence.

A YAML sequence is basically a list, and looks like this:

%YAML 1.1
---
- I am
- a Sequence

A YAML sequence may have an anchor like this:

%YAML 1.1
---
&A [
  "This sequence",
  "has an anchor"
]

A YAML sequence may also have a tag like this:

%YAML 1.1
---
!!seq [
  "This sequence",
  "has a tag"
]

This class represents a sequence in a YAML document. A Psych::Nodes::Sequence node may have 0 or more children. Valid children for this node are:

  • Psych::Nodes::Sequence

  • Psych::Nodes::Mapping

  • Psych::Nodes::Scalar

  • Psych::Nodes::Alias

In Files

  • ext/psych/lib/psych/nodes/sequence.rb

Parent

Psych::Nodes::Node

Constants

ANY

Any Styles, emitter chooses

BLOCK

Block style sequence

FLOW

Flow style sequence

Attributes

anchor[RW]

The anchor for this sequence (if any)

implicit[RW]

Is this sequence started implicitly?

style[RW]

The sequece style used

tag[RW]

The tag name for this sequence (if any)

Public Class Methods

new(anchor = nil, tag = nil, implicit = true, style = BLOCK) click to toggle source

Create a new object representing a YAML sequence.

anchor is the anchor associated with the sequence or nil. tag is the tag associated with the sequence or nil. implicit a boolean indicating whether or not the sequence was implicitly started. style is an integer indicating the list style.

See Psych::Handler#start_sequence

# File ext/psych/lib/psych/nodes/sequence.rb, line 72
def initialize anchor = nil, tag = nil, implicit = true, style = BLOCK
  super()
  @anchor   = anchor
  @tag      = tag
  @implicit = implicit
  @style    = style
end


class Psych::Nodes::Stream - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Nodes::Stream

Represents a YAML stream. This is the root node for any YAML parse tree. This node must have one or more child nodes. The only valid child node for a Psych::Nodes::Stream node is Psych::Nodes::Document.

In Files

  • ext/psych/lib/psych/nodes/stream.rb

Parent

Psych::Nodes::Node

Constants

ANY

Any encoding

UTF16BE

UTF-16BE encoding

UTF16LE

UTF-16LE encoding

UTF8

UTF-8 encoding

Attributes

encoding[RW]

The encoding used for this stream

Public Class Methods

new(encoding = UTF8) click to toggle source

Create a new Psych::Nodes::Stream node with an encoding that defaults to Psych::Nodes::Stream::UTF8.

See also Psych::Handler#start_stream

# File ext/psych/lib/psych/nodes/stream.rb, line 31
def initialize encoding = UTF8
  super()
  @encoding = encoding
end


class Psych::Omap - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Omap

In Files

  • ext/psych/lib/psych/omap.rb

Parent

Hash


class Psych::Parser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Parser

YAML event parser class. This class parses a YAML document and calls events on the handler that is passed to the constructor. The events can be used for things such as constructing a YAML AST or deserializing YAML documents. It can even be fed back to Psych::Emitter to emit the same document that was parsed.

See Psych::Handler for documentation on the events that Psych::Parser emits.

Here is an example that prints out ever scalar found in a YAML document:

# Handler for detecting scalar values
class ScalarHandler < Psych::Handler
  def scalar value, anchor, tag, plain, quoted, style
    puts value
  end
end

parser = Psych::Parser.new(ScalarHandler.new)
parser.parse(yaml_document)

Here is an example that feeds the parser back in to Psych::Emitter. The YAML document is read from STDIN and written back out to STDERR:

parser = Psych::Parser.new(Psych::Emitter.new($stderr))
parser.parse($stdin)

Psych uses Psych::Parser in combination with Psych::TreeBuilder to construct an AST of the parsed YAML document.

In Files

  • ext/psych/lib/psych/parser.rb

Parent

Object

Attributes

external_encoding[W]

Set the encoding for this parser to encoding

handler[RW]

The handler on which events will be called

Public Class Methods

new(handler = Handler.new) click to toggle source

Creates a new Psych::Parser instance with handler. YAML events will be called on handler. See Psych::Parser for more details.

# File ext/psych/lib/psych/parser.rb, line 46
def initialize handler = Handler.new
  @handler = handler
  @external_encoding = ANY
end


class Psych::Parser::Mark - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Parser::Mark

In Files

  • ext/psych/lib/psych/parser.rb

Parent

Struct.new(:index, :line, :column)


class Psych::PrivateType - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::PrivateType

In Files

  • lib/rubygems/psych_additions.rb

Parent

Object


class Psych::ScalarScanner - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::ScalarScanner

Scan scalars for built in types

In Files

  • ext/psych/lib/psych/scalar_scanner.rb

Parent

Object

Constants

FLOAT

Taken from yaml.org/type/float.html

INTEGER

Taken from yaml.org/type/int.html

TIME

Taken from yaml.org/type/timestamp.html

Public Class Methods

new() click to toggle source

Create a new scanner

# File ext/psych/lib/psych/scalar_scanner.rb, line 23
def initialize
  @string_cache = {}
  @symbol_cache = {}
end

Public Instance Methods

parse_int(string) click to toggle source

Parse and return an int from string

# File ext/psych/lib/psych/scalar_scanner.rb, line 112
def parse_int string
  return unless INTEGER === string
  Integer(string)
end
parse_time(string) click to toggle source

Parse and return a Time from string

# File ext/psych/lib/psych/scalar_scanner.rb, line 119
def parse_time string
  date, time = *(string.split(/[ tT]/, 2))
  (yy, m, dd) = date.split('-').map { |x| x.to_i }
  md = time.match(/(\d+:\d+:\d+)(?:\.(\d*))?\s*(Z|[-+]\d+(:\d\d)?)?/)

  (hh, mm, ss) = md[1].split(':').map { |x| x.to_i }
  us = (md[2] ? Rational("0.#{md[2]}") : 0) * 1000000

  time = Time.utc(yy, m, dd, hh, mm, ss, us)

  return time if 'Z' == md[3]
  return Time.at(time.to_i, us) unless md[3]

  tz = md[3].match(/^([+\-]?\d{1,2})\:?(\d{1,2})?$/)[1..-1].compact.map { |digit| Integer(digit, 10) }
  offset = tz.first * 3600

  if offset < 0
    offset -= ((tz[1] || 0) * 60)
  else
    offset += ((tz[1] || 0) * 60)
  end

  Time.at((time - offset).to_i, us)
end
tokenize(string) click to toggle source

Tokenize string returning the ruby object

# File ext/psych/lib/psych/scalar_scanner.rb, line 29
def tokenize string
  return nil if string.empty?
  return string if @string_cache.key?(string)
  return @symbol_cache[string] if @symbol_cache.key?(string)

  case string
  # Check for a String type, being careful not to get caught by hash keys, hex values, and
  # special floats (e.g., -.inf).
  when /^[^\d\.:-]?[A-Za-z_\s!@#\$%\^&\*\(\)\{\}\<\>\|\/\~;=]+/
    if string.length > 5
      @string_cache[string] = true
      return string
    end

    case string
    when /^[^ytonf~]/
      @string_cache[string] = true
      string
    when '~', /^null$/
      nil
    when /^(yes|true|on)$/
      true
    when /^(no|false|off)$/
      false
    else
      @string_cache[string] = true
      string
    end
  when TIME
    begin
      parse_time string
    rescue ArgumentError
      string
    end
  when /^\d{4}-(?:1[012]|0\d|\d)-(?:[12]\d|3[01]|0\d|\d)$/
    require 'date'
    begin
      Date.strptime(string, '%Y-%m-%d')
    rescue ArgumentError
      string
    end
  when /^\.inf$/
    Float::INFINITY
  when /^-\.inf$/
    -Float::INFINITY
  when /^\.nan$/
    Float::NAN
  when /^:./
    if string =~ /^:(["'])(.*)\1/
      @symbol_cache[string] = $2.sub(/^:/, '').to_sym
    else
      @symbol_cache[string] = string.sub(/^:/, '').to_sym
    end
  when /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+$/
    i = 0
    string.split(':').each_with_index do |n,e|
      i += (n.to_i * 60 ** (e - 2).abs)
    end
    i
  when /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*$/
    i = 0
    string.split(':').each_with_index do |n,e|
      i += (n.to_f * 60 ** (e - 2).abs)
    end
    i
  when FLOAT
    if string == '.'
      @string_cache[string] = true
      string
    else
      Float(string.gsub(/[,_]|\.$/, ''))
    end
  else
    int = parse_int string.gsub(/[,_]/, '')
    return int if int

    @string_cache[string] = true
    string
  end
end


class Psych::Set - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Set

In Files

  • ext/psych/lib/psych/set.rb

Parent

Hash


class Psych::Stream - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Stream

Psych::Stream is a streaming YAML emitter. It will not buffer your YAML, but send it straight to an IO.

Here is an example use:

stream = Psych::Stream.new($stdout)
stream.start
stream.push({:foo => 'bar'})
stream.finish

YAML will be immediately emitted to $stdout with no buffering.

Psych::Streaming#start will take a block and ensure that Psych::Visitors::YAMLTree#finish is called, so you can do this form:

stream = Psych::Stream.new($stdout)
stream.start do |em|
  em.push(:foo => 'bar')
end

In Files

  • ext/psych/lib/psych/stream.rb

Parent

Psych::Visitors::YAMLTree

Included Modules

  • Psych::Streaming


module Psych::Streaming - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Psych::Streaming

In Files

  • ext/psych/lib/psych/streaming.rb

Public Class Methods

new(io) click to toggle source

Create a new streaming emitter. Emitter will print to io. See Psych::Stream for an example.

# File ext/psych/lib/psych/streaming.rb, line 6
def initialize io
  super({}, self.class.const_get(:Emitter).new(io))
end

Public Instance Methods

start(encoding = Nodes::Stream::UTF8) { |self| ... } click to toggle source

Start streaming using encoding

# File ext/psych/lib/psych/streaming.rb, line 12
def start encoding = Nodes::Stream::UTF8
  super.tap { yield self if block_given?  }
ensure
  finish if block_given?
end


class Psych::SyntaxError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::SyntaxError

In Files

  • ext/psych/lib/psych/syntax_error.rb

Parent

Psych::Error

Attributes

column[R]
context[R]
file[R]
line[R]
offset[R]
problem[R]

Public Class Methods

new(file, line, col, offset, problem, context) click to toggle source
# File ext/psych/lib/psych/syntax_error.rb, line 8
def initialize file, line, col, offset, problem, context
  err      = [problem, context].compact.join ' '
  filename = file || '<unknown>'
  message  = "(%s): %s at line %d column %d" % [filename, err, line, col]

  @file    = file
  @line    = line
  @column  = col
  @offset  = offset
  @problem = problem
  @context = context
  super(message)
end


class Psych::TreeBuilder - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::TreeBuilder

This class works in conjunction with Psych::Parser to build an in-memory parse tree that represents a YAML document.

Example

parser = Psych::Parser.new Psych::TreeBuilder.new
parser.parse('--- foo')
tree = parser.handler.root

See Psych::Handler for documentation on the event methods used in this class.

In Files

  • ext/psych/lib/psych/tree_builder.rb

Parent

Psych::Handler

Attributes

root[R]

Returns the root node for the built tree

Public Class Methods

new() click to toggle source

Create a new TreeBuilder instance

# File ext/psych/lib/psych/tree_builder.rb, line 21
def initialize
  @stack = []
  @last  = nil
  @root  = nil
end

Public Instance Methods

alias(anchor) click to toggle source
# File ext/psych/lib/psych/tree_builder.rb, line 80
def alias anchor
  @last.children << Nodes::Alias.new(anchor)
end
end_document(implicit_end = !streaming?) click to toggle source

Handles #end_document events with version, tag_directives, and implicit styling.

See Psych::Handler#start_document

# File ext/psych/lib/psych/tree_builder.rb, line 60
def end_document implicit_end = !streaming?
  @last.implicit_end = implicit_end
  pop
end
end_stream() click to toggle source
# File ext/psych/lib/psych/tree_builder.rb, line 70
def end_stream
  pop
end
scalar(value, anchor, tag, plain, quoted, style) click to toggle source
# File ext/psych/lib/psych/tree_builder.rb, line 74
def scalar value, anchor, tag, plain, quoted, style
  s = Nodes::Scalar.new(value,anchor,tag,plain,quoted,style)
  @last.children << s
  s
end
start_document(version, tag_directives, implicit) click to toggle source

Handles #start_document events with version, tag_directives, and implicit styling.

See Psych::Handler#start_document

# File ext/psych/lib/psych/tree_builder.rb, line 49
def start_document version, tag_directives, implicit
  n = Nodes::Document.new version, tag_directives, implicit
  @last.children << n
  push n
end
start_stream(encoding) click to toggle source
# File ext/psych/lib/psych/tree_builder.rb, line 65
def start_stream encoding
  @root = Nodes::Stream.new(encoding)
  push @root
end


module Psych::Visitors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Psych::Visitors

In Files

  • ext/psych/lib/psych/visitors/depth_first.rb
  • ext/psych/lib/psych/visitors/emitter.rb
  • ext/psych/lib/psych/visitors/json_tree.rb
  • ext/psych/lib/psych/visitors/to_ruby.rb
  • ext/psych/lib/psych/visitors/visitor.rb
  • ext/psych/lib/psych/visitors/yaml_tree.rb


class Psych::Visitors::DepthFirst - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Visitors::DepthFirst

In Files

  • ext/psych/lib/psych/visitors/depth_first.rb

Parent

Psych::Visitors::Visitor

Public Class Methods

new(block) click to toggle source
# File ext/psych/lib/psych/visitors/depth_first.rb, line 4
def initialize block
  @block = block
end


class Psych::Visitors::Emitter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Visitors::Emitter

In Files

  • ext/psych/lib/psych/visitors/emitter.rb

Parent

Psych::Visitors::Visitor

Public Class Methods

new(io, options = {}) click to toggle source
# File ext/psych/lib/psych/visitors/emitter.rb, line 4
def initialize io, options = {}
  opts = [:indentation, :canonical, :line_width].find_all { |opt|
    options.key?(opt)
  }

  if opts.empty?
    @handler = Psych::Emitter.new io
  else
    du = Handler::DumperOptions.new
    opts.each { |option| du.send :"#{option}=", options[option] }
    @handler = Psych::Emitter.new io, du
  end
end

Public Instance Methods

visit_Psych_Nodes_Alias(o) click to toggle source
# File ext/psych/lib/psych/visitors/emitter.rb, line 46
def visit_Psych_Nodes_Alias o
  @handler.alias o.anchor
end
visit_Psych_Nodes_Document(o) click to toggle source
# File ext/psych/lib/psych/visitors/emitter.rb, line 24
def visit_Psych_Nodes_Document o
  @handler.start_document o.version, o.tag_directives, o.implicit
  o.children.each { |c| accept c }
  @handler.end_document o.implicit_end
end
visit_Psych_Nodes_Mapping(o) click to toggle source
# File ext/psych/lib/psych/visitors/emitter.rb, line 40
def visit_Psych_Nodes_Mapping o
  @handler.start_mapping o.anchor, o.tag, o.implicit, o.style
  o.children.each { |c| accept c }
  @handler.end_mapping
end
visit_Psych_Nodes_Scalar(o) click to toggle source
# File ext/psych/lib/psych/visitors/emitter.rb, line 30
def visit_Psych_Nodes_Scalar o
  @handler.scalar o.value, o.anchor, o.tag, o.plain, o.quoted, o.style
end
visit_Psych_Nodes_Sequence(o) click to toggle source
# File ext/psych/lib/psych/visitors/emitter.rb, line 34
def visit_Psych_Nodes_Sequence o
  @handler.start_sequence o.anchor, o.tag, o.implicit, o.style
  o.children.each { |c| accept c }
  @handler.end_sequence
end
visit_Psych_Nodes_Stream(o) click to toggle source
# File ext/psych/lib/psych/visitors/emitter.rb, line 18
def visit_Psych_Nodes_Stream o
  @handler.start_stream o.encoding
  o.children.each { |c| accept c }
  @handler.end_stream
end


class Psych::Visitors::JSONTree - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Visitors::JSONTree

In Files

  • ext/psych/lib/psych/visitors/json_tree.rb

Parent

YAMLTree

Public Class Methods

new(options = {}) click to toggle source
# File ext/psych/lib/psych/visitors/json_tree.rb, line 8
def initialize options = {}, emitter = Psych::JSON::TreeBuilder.new
  super
end

Public Instance Methods

accept(target) click to toggle source
# File ext/psych/lib/psych/visitors/json_tree.rb, line 12
def accept target
  if target.respond_to?(:encode_with)
    dump_coder target
  else
    send(@dispatch_cache[target.class], target)
  end
end


class Psych::Visitors::ToRuby - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Visitors::ToRuby

This class walks a YAML AST, converting each node to ruby

In Files

  • ext/psych/lib/psych/visitors/to_ruby.rb

Parent

Psych::Visitors::Visitor

Public Class Methods

new(ss = ScalarScanner.new) click to toggle source
# File ext/psych/lib/psych/visitors/to_ruby.rb, line 12
def initialize ss = ScalarScanner.new
  super()
  @st = {}
  @ss = ss
  @domain_types = Psych.domain_types
end

Public Instance Methods

accept(target) click to toggle source
# File ext/psych/lib/psych/visitors/to_ruby.rb, line 19
def accept target
  result = super
  return result if @domain_types.empty? || !target.tag

  key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:')
  key = "tag:#{key}" unless key =~ /^(tag:|x-private)/

  if @domain_types.key? key
    value, block = @domain_types[key]
    return block.call value, result
  end

  result
end
visit_Psych_Nodes_Alias(o) click to toggle source
# File ext/psych/lib/psych/visitors/to_ruby.rb, line 247
def visit_Psych_Nodes_Alias o
  @st.fetch(o.anchor) { raise BadAlias, "Unknown alias: #{o.anchor}" }
end
visit_Psych_Nodes_Document(o) click to toggle source
# File ext/psych/lib/psych/visitors/to_ruby.rb, line 239
def visit_Psych_Nodes_Document o
  accept o.root
end
visit_Psych_Nodes_Mapping(o) click to toggle source
# File ext/psych/lib/psych/visitors/to_ruby.rb, line 139
def visit_Psych_Nodes_Mapping o
  return revive(Psych.load_tags[o.tag], o) if Psych.load_tags[o.tag]
  return revive_hash({}, o) unless o.tag

  case o.tag
  when /^!ruby\/struct:?(.*)?$/
    klass = resolve_class($1)

    if klass
      s = register(o, klass.allocate)

      members = {}
      struct_members = s.members.map { |x| x.to_sym }
      o.children.each_slice(2) do |k,v|
        member = accept(k)
        value  = accept(v)
        if struct_members.include?(member.to_sym)
          s.send("#{member}=", value)
        else
          members[member.to_s.sub(/^@/, '')] = value
        end
      end
      init_with(s, members, o)
    else
      members = o.children.map { |c| accept c }
      h = Hash[*members]
      Struct.new(*h.map { |k,v| k.to_sym }).new(*h.map { |k,v| v })
    end

  when /^!ruby\/object:?(.*)?$/
    name = $1 || 'Object'

    if name == 'Complex'
      h = Hash[*o.children.map { |c| accept c }]
      register o, Complex(h['real'], h['image'])
    elsif name == 'Rational'
      h = Hash[*o.children.map { |c| accept c }]
      register o, Rational(h['numerator'], h['denominator'])
    else
      obj = revive((resolve_class(name) || Object), o)
      obj
    end

  when /^!(?:str|ruby\/string)(?::(.*))?/, 'tag:yaml.org,2002:str'
    klass = resolve_class($1)
    members = Hash[*o.children.map { |c| accept c }]
    string = members.delete 'str'

    if klass
      string = klass.allocate.replace string
      register(o, string)
    end

    init_with(string, members.map { |k,v| [k.to_s.sub(/^@/, ''),v] }, o)
  when /^!ruby\/array:(.*)$/
    klass = resolve_class($1)
    list  = register(o, klass.allocate)

    members = Hash[o.children.map { |c| accept c }.each_slice(2).to_a]
    list.replace members['internal']

    members['ivars'].each do |ivar, v|
      list.instance_variable_set ivar, v
    end
    list

  when '!ruby/range'
    h = Hash[*o.children.map { |c| accept c }]
    register o, Range.new(h['begin'], h['end'], h['excl'])

  when /^!ruby\/exception:?(.*)?$/
    h = Hash[*o.children.map { |c| accept c }]

    e = build_exception((resolve_class($1) || Exception),
                        h.delete('message'))
    init_with(e, h, o)

  when '!set', 'tag:yaml.org,2002:set'
    set = Psych::Set.new
    @st[o.anchor] = set if o.anchor
    o.children.each_slice(2) do |k,v|
      set[accept(k)] = accept(v)
    end
    set

  when /^!map:(.*)$/, /^!ruby\/hash:(.*)$/
    revive_hash resolve_class($1).new, o

  when '!omap', 'tag:yaml.org,2002:omap'
    map = register(o, Psych::Omap.new)
    o.children.each_slice(2) do |l,r|
      map[accept(l)] = accept r
    end
    map

  else
    revive_hash({}, o)
  end
end
visit_Psych_Nodes_Scalar(o) click to toggle source
# File ext/psych/lib/psych/visitors/to_ruby.rb, line 103
def visit_Psych_Nodes_Scalar o
  register o, deserialize(o)
end
visit_Psych_Nodes_Sequence(o) click to toggle source
# File ext/psych/lib/psych/visitors/to_ruby.rb, line 107
def visit_Psych_Nodes_Sequence o
  if klass = Psych.load_tags[o.tag]
    instance = klass.allocate

    if instance.respond_to?(:init_with)
      coder = Psych::Coder.new(o.tag)
      coder.seq = o.children.map { |c| accept c }
      instance.init_with coder
    end

    return instance
  end

  case o.tag
  when nil
    register_empty(o)
  when '!omap', 'tag:yaml.org,2002:omap'
    map = register(o, Psych::Omap.new)
    o.children.each { |a|
      map[accept(a.children.first)] = accept a.children.last
    }
    map
  when /^!(?:seq|ruby\/array):(.*)$/
    klass = resolve_class($1)
    list  = register(o, klass.allocate)
    o.children.each { |c| list.push accept c }
    list
  else
    register_empty(o)
  end
end
visit_Psych_Nodes_Stream(o) click to toggle source
# File ext/psych/lib/psych/visitors/to_ruby.rb, line 243
def visit_Psych_Nodes_Stream o
  o.children.map { |c| accept c }
end


class Psych::Visitors::Visitor - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Visitors::Visitor

In Files

  • ext/psych/lib/psych/visitors/visitor.rb

Parent

Object

Constants

DISPATCH

Public Instance Methods

accept(target) click to toggle source
# File ext/psych/lib/psych/visitors/visitor.rb, line 4
def accept target
  visit target
end


class Psych::Visitors::YAMLTree - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Psych::Visitors::YAMLTree

YAMLTree builds a YAML ast given a ruby object. For example:

builder = Psych::Visitors::YAMLTree.new
builder << { :foo => 'bar' }
builder.tree # => #<Psych::Nodes::Stream .. }

In Files

  • ext/psych/lib/psych/visitors/yaml_tree.rb

Parent

Psych::Visitors::Visitor

Attributes

finished[R]
finished?[R]
started[R]
started?[R]

Public Class Methods

new(options = {}) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 39
def initialize options = {}, emitter = TreeBuilder.new, ss = ScalarScanner.new
  super()
  @started  = false
  @finished = false
  @emitter  = emitter
  @st       = Registrar.new
  @ss       = ss
  @options  = options
  @coders   = []

  @dispatch_cache = Hash.new do |h,klass|
    method = "visit_#{(klass.name || '').split('::').join('_')}"

    method = respond_to?(method) ? method : h[klass.superclass]

    raise(TypeError, "Can't dump #{target.class}") unless method

    h[klass] = method
  end
end

Public Instance Methods

<<(object) click to toggle source
Alias for: push
accept(target) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 97
def accept target
  # return any aliases we find
  if @st.key? target
    oid         = @st.id_for target
    node        = @st.node_for target
    anchor      = oid.to_s
    node.anchor = anchor
    return @emitter.alias anchor
  end

  if target.respond_to?(:to_yaml)
    begin
      loc = target.method(:to_yaml).source_location.first
      if loc !~ /(syck\/rubytypes.rb|psych\/core_ext.rb)/
        unless target.respond_to?(:encode_with)
          if $VERBOSE
            warn "implementing to_yaml is deprecated, please implement \"encode_with\""
          end

          target.to_yaml(:nodump => true)
        end
      end
    rescue
      # public_method or source_location might be overridden,
      # and it's OK to skip it since it's only to emit a warning
    end
  end

  if target.respond_to?(:encode_with)
    dump_coder target
  else
    send(@dispatch_cache[target.class], target)
  end
end
finish() click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 66
def finish
  @emitter.end_stream.tap do
    @finished = true
  end
end
push(object) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 77
def push object
  start unless started?
  version = []
  version = [1,1] if @options[:header]

  case @options[:version]
  when Array
    version = @options[:version]
  when String
    version = @options[:version].split('.').map { |x| x.to_i }
  else
    version = [1,1]
  end if @options.key? :version

  @emitter.start_document version, [], false
  accept object
  @emitter.end_document !@emitter.streaming?
end
Also aliased as: <<
start(encoding = Nodes::Stream::UTF8) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 60
def start encoding = Nodes::Stream::UTF8
  @emitter.start_stream(encoding).tap do
    @started = true
  end
end
tree() click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 72
def tree
  finish unless finished?
  @emitter.root
end
visit_Array(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 341
def visit_Array o
  if o.class == ::Array
    register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK)
    o.each { |c| accept c }
    @emitter.end_sequence
  else
    visit_array_subclass o
  end
end
visit_BigDecimal(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 243
def visit_BigDecimal o
  @emitter.scalar o._dump, nil, '!ruby/object:BigDecimal', false, false, Nodes::Scalar::ANY
end
visit_Class(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 303
def visit_Class o
  raise TypeError, "can't dump anonymous class: #{o}" unless o.name
  register o, @emitter.scalar(o.name, nil, '!ruby/class', false, false, Nodes::Scalar::SINGLE_QUOTED)
end
visit_Complex(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 215
def visit_Complex o
  register o, @emitter.start_mapping(nil, '!ruby/object:Complex', false, Nodes::Mapping::BLOCK)

  ['real', o.real.to_s, 'image', o.imag.to_s].each do |m|
    @emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY
  end

  @emitter.end_mapping
end
visit_Date(o) click to toggle source
Alias for: visit_Integer
visit_DateTime(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 191
def visit_DateTime o
  formatted = format_time o.to_time
  tag = '!ruby/object:DateTime'
  register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY)
end
visit_Exception(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 168
def visit_Exception o
  tag = ['!ruby/exception', o.class.name].join ':'

  @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK

  {
    'message'   => private_iv_get(o, 'mesg'),
    'backtrace' => private_iv_get(o, 'backtrace'),
  }.each do |k,v|
    next unless v
    @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
    accept v
  end

  dump_ivars o

  @emitter.end_mapping
end
visit_FalseClass(o) click to toggle source
Alias for: visit_Integer
visit_Float(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 232
def visit_Float o
  if o.nan?
    @emitter.scalar '.nan', nil, nil, true, false, Nodes::Scalar::ANY
  elsif o.infinite?
    @emitter.scalar((o.infinite? > 0 ? '.inf' : '-.inf'),
      nil, nil, true, false, Nodes::Scalar::ANY)
  else
    @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY
  end
end
visit_Hash(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 316
def visit_Hash o
  tag      = o.class == ::Hash ? nil : "!ruby/hash:#{o.class}"
  implicit = !tag

  register(o, @emitter.start_mapping(nil, tag, implicit, Psych::Nodes::Mapping::BLOCK))

  o.each do |k,v|
    accept k
    accept v
  end

  @emitter.end_mapping
end
visit_Integer(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 225
def visit_Integer o
  @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY
end
Also aliased as: visit_TrueClass, visit_FalseClass, visit_Date
visit_Module(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 298
def visit_Module o
  raise TypeError, "can't dump anonymous module: #{o}" unless o.name
  register o, @emitter.scalar(o.name, nil, '!ruby/module', false, false, Nodes::Scalar::SINGLE_QUOTED)
end
visit_NilClass(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 351
def visit_NilClass o
  @emitter.scalar('', nil, 'tag:yaml.org,2002:null', true, false, Nodes::Scalar::ANY)
end
visit_Object(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 140
def visit_Object o
  tag = Psych.dump_tags[o.class]
  unless tag
    klass = o.class == Object ? nil : o.class.name
    tag   = ['!ruby/object', klass].compact.join(':')
  end

  map = @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK)
  register(o, map)

  dump_ivars o
  @emitter.end_mapping
end
visit_Psych_Omap(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 132
def visit_Psych_Omap o
  seq = @emitter.start_sequence(nil, '!omap', false, Nodes::Sequence::BLOCK)
  register(o, seq)

  o.each { |k,v| visit_Hash k => v }
  @emitter.end_sequence
end
visit_Psych_Set(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 330
def visit_Psych_Set o
  register(o, @emitter.start_mapping(nil, '!set', false, Psych::Nodes::Mapping::BLOCK))

  o.each do |k,v|
    accept k
    accept v
  end

  @emitter.end_mapping
end
visit_Range(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 308
def visit_Range o
  register o, @emitter.start_mapping(nil, '!ruby/range', false, Nodes::Mapping::BLOCK)
  ['begin', o.begin, 'end', o.end, 'excl', o.exclude_end?].each do |m|
    accept m
  end
  @emitter.end_mapping
end
visit_Rational(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 202
def visit_Rational o
  register o, @emitter.start_mapping(nil, '!ruby/object:Rational', false, Nodes::Mapping::BLOCK)

  [
    'denominator', o.denominator.to_s,
    'numerator', o.numerator.to_s
  ].each do |m|
    @emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY
  end

  @emitter.end_mapping
end
visit_Regexp(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 187
def visit_Regexp o
  register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY)
end
visit_String(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 255
def visit_String o
  plain = true
  quote = true
  style = Nodes::Scalar::PLAIN
  tag   = nil
  str   = o

  if binary?(o)
    str   = [o].pack('m').chomp
    tag   = '!binary' # FIXME: change to below when syck is removed
    #tag   = 'tag:yaml.org,2002:binary'
    style = Nodes::Scalar::LITERAL
    plain = false
    quote = false
  elsif o =~ /\n/
    style = Nodes::Scalar::LITERAL
  else
    unless String === @ss.tokenize(o)
      style = Nodes::Scalar::SINGLE_QUOTED
    end
  end

  ivars = find_ivars o

  if ivars.empty?
    unless o.class == ::String
      tag = "!ruby/string:#{o.class}"
    end
    @emitter.scalar str, nil, tag, plain, quote, style
  else
    maptag = '!ruby/string'
    maptag << ":#{o.class}" unless o.class == ::String

    register o, @emitter.start_mapping(nil, maptag, false, Nodes::Mapping::BLOCK)
    @emitter.scalar 'str', nil, nil, true, false, Nodes::Scalar::ANY
    @emitter.scalar str, nil, tag, plain, quote, style

    dump_ivars o

    @emitter.end_mapping
  end
end
visit_Struct(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 154
def visit_Struct o
  tag = ['!ruby/struct', o.class.name].compact.join(':')

  register o, @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK)
  o.members.each do |member|
    @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY
    accept o[member]
  end

  dump_ivars o

  @emitter.end_mapping
end
visit_Symbol(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 355
def visit_Symbol o
  @emitter.scalar ":#{o}", nil, nil, true, false, Nodes::Scalar::ANY
end
visit_Time(o) click to toggle source
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 197
def visit_Time o
  formatted = format_time o
  @emitter.scalar formatted, nil, nil, true, false, Nodes::Scalar::ANY
end
visit_TrueClass(o) click to toggle source
Alias for: visit_Integer


class Queue - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Queue

This class provides a way to synchronize communication between threads.

Example:

require 'thread'

queue = Queue.new

producer = Thread.new do
  5.times do |i|
    sleep rand(i) # simulate expense
    queue << i
    puts "#{i} produced"
  end
end

consumer = Thread.new do
  5.times do |i|
    value = queue.pop
    sleep rand(i/2) # simulate expense
    puts "consumed #{value}"
  end
end

consumer.join

In Files

  • lib/thread.rb

Parent

Object

Public Class Methods

new() click to toggle source

Creates a new queue.

# File lib/thread.rb, line 150
def initialize
  @que = []
  @que.taint          # enable tainted communication
  @num_waiting = 0
  self.taint
  @mutex = Mutex.new
  @cond = ConditionVariable.new
end

Public Instance Methods

<<(obj) click to toggle source

Alias of push

Alias for: push
clear() click to toggle source

Removes all objects from the queue.

# File lib/thread.rb, line 229
def clear
  @que.clear
end
deq(non_block=false) click to toggle source

Alias of pop

Alias for: pop
empty?() click to toggle source

Returns true if the queue is empty.

# File lib/thread.rb, line 222
def empty?
  @que.empty?
end
enq(obj) click to toggle source

Alias of push

Alias for: push
length() click to toggle source

Returns the length of the queue.

# File lib/thread.rb, line 236
def length
  @que.length
end
Also aliased as: size
num_waiting() click to toggle source

Returns the number of threads waiting on the queue.

# File lib/thread.rb, line 248
def num_waiting
  @num_waiting
end
pop(non_block=false) click to toggle source

Retrieves data from the queue. If the queue is empty, the calling thread is suspended until data is pushed onto the queue. If non_block is true, the thread isn't suspended, and an exception is raised.

# File lib/thread.rb, line 186
def pop(non_block=false)
  Thread.handle_interrupt(StandardError => :on_blocking) do
    @mutex.synchronize do
      while true
        if @que.empty?
          if non_block
            raise ThreadError, "queue empty"
          else
            begin
              @num_waiting += 1
              @cond.wait @mutex
            ensure
              @num_waiting -= 1
            end
          end
        else
          return @que.shift
        end
      end
    end
  end
end
Also aliased as: shift, deq
push(obj) click to toggle source

Pushes obj to the queue.

# File lib/thread.rb, line 162
def push(obj)
  Thread.handle_interrupt(StandardError => :on_blocking) do
    @mutex.synchronize do
      @que.push obj
      @cond.signal
    end
  end
end
Also aliased as: <<, enq
shift(non_block=false) click to toggle source

Alias of pop

Alias for: pop
size() click to toggle source

Alias of length.

Alias for: length


module REXML - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML

:element, parent, name, attributes, children*

a = Node.new a << “B” # => <a>B</a> a.b # => <a>B<b/></a> a.b # => <a>B<b/><b/><a> a.b[“x”] = “y” # => <a>B<b/><b x=“y”/></a> a.b.c # => <a>B<c/><b x=“y”/></a> a.b.c << “D” # => <a>B<c>D</c><b x=“y”/></a>

REXML is an XML toolkit for Ruby, in Ruby.

REXML is a pure Ruby, XML 1.0 conforming, non-validating toolkit with an intuitive API. REXML passes 100% of the non-validating Oasis tests, and provides tree, stream, SAX2, pull, and lightweight APIs. REXML also includes a full XPath 1.0 implementation. Since Ruby 1.8, REXML is included in the standard Ruby distribution.

Main page

www.germane-software.com/software/rexml

Author

Sean Russell <serATgermaneHYPHENsoftwareDOTcom>

Date

2008/019

Version

3.1.7.3

This API documentation can be downloaded from the REXML home page, or can be accessed online

A tutorial is available in the REXML distribution in docs/tutorial.html, or can be accessed online

In Files

  • lib/rexml/attlistdecl.rb
  • lib/rexml/attribute.rb
  • lib/rexml/cdata.rb
  • lib/rexml/child.rb
  • lib/rexml/comment.rb
  • lib/rexml/doctype.rb
  • lib/rexml/document.rb
  • lib/rexml/dtd/attlistdecl.rb
  • lib/rexml/dtd/dtd.rb
  • lib/rexml/dtd/elementdecl.rb
  • lib/rexml/dtd/entitydecl.rb
  • lib/rexml/dtd/notationdecl.rb
  • lib/rexml/element.rb
  • lib/rexml/encoding.rb
  • lib/rexml/entity.rb
  • lib/rexml/formatters/default.rb
  • lib/rexml/formatters/pretty.rb
  • lib/rexml/formatters/transitive.rb
  • lib/rexml/functions.rb
  • lib/rexml/instruction.rb
  • lib/rexml/light/node.rb
  • lib/rexml/namespace.rb
  • lib/rexml/node.rb
  • lib/rexml/output.rb
  • lib/rexml/parent.rb
  • lib/rexml/parseexception.rb
  • lib/rexml/parsers/baseparser.rb
  • lib/rexml/parsers/lightparser.rb
  • lib/rexml/parsers/pullparser.rb
  • lib/rexml/parsers/sax2parser.rb
  • lib/rexml/parsers/streamparser.rb
  • lib/rexml/parsers/treeparser.rb
  • lib/rexml/parsers/ultralightparser.rb
  • lib/rexml/parsers/xpathparser.rb
  • lib/rexml/quickpath.rb
  • lib/rexml/rexml.rb
  • lib/rexml/sax2listener.rb
  • lib/rexml/source.rb
  • lib/rexml/streamlistener.rb
  • lib/rexml/syncenumerator.rb
  • lib/rexml/text.rb
  • lib/rexml/undefinednamespaceexception.rb
  • lib/rexml/validation/relaxng.rb
  • lib/rexml/validation/validation.rb
  • lib/rexml/validation/validationexception.rb
  • lib/rexml/xmldecl.rb
  • lib/rexml/xmltokens.rb
  • lib/rexml/xpath.rb
  • lib/rexml/xpath_parser.rb

Constants

COPYRIGHT
Copyright
DATE
REVISION
VERSION
Version

Public Class Methods

entity_expansion_text_limit() click to toggle source

Get the entity expansion limit. By default the limit is set to 10240.

# File lib/rexml/rexml.rb, line 39
def self.entity_expansion_text_limit
  return @@entity_expansion_text_limit
end
entity_expansion_text_limit=( val ) click to toggle source

Set the entity expansion limit. By default the limit is set to 10240.

# File lib/rexml/rexml.rb, line 34
def self.entity_expansion_text_limit=( val )
  @@entity_expansion_text_limit = val
end


class REXML::AttlistDecl - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::AttlistDecl

This class needs:

  • Documentation

  • Work! Not all types of attlists are intelligently parsed, so we just

spew back out what we get in. This works, but it would be better if we formatted the output ourselves.

AttlistDecls provide just enough support to allow namespace declarations. If you need some sort of generalized support, or have an interesting idea about how to map the hideous, terrible design of DTD AttlistDecls onto an intuitive Ruby interface, let me know. I'm desperate for anything to make DTDs more palateable.

In Files

  • lib/rexml/attlistdecl.rb

Parent

Child

Included Modules

  • Enumerable

Attributes

element_name[R]

What is this? Got me.

Public Class Methods

new(source) click to toggle source

Create an AttlistDecl, pulling the information from a Source. Notice that this isn't very convenient; to create an AttlistDecl, you basically have to format it yourself, and then have the initializer parse it. Sorry, but for the forseeable future, DTD support in REXML is pretty weak on convenience. Have I mentioned how much I hate DTDs?

# File lib/rexml/attlistdecl.rb, line 28
def initialize(source)
  super()
  if (source.kind_of? Array)
    @element_name, @pairs, @contents = *source
  end
end

Public Instance Methods

[](key) click to toggle source

Access the attlist attribute/value pairs.

value = attlist_decl[ attribute_name ]
# File lib/rexml/attlistdecl.rb, line 37
def [](key)
  @pairs[key]
end
each(&block) click to toggle source

Iterate over the key/value pairs:

attlist_decl.each { |attribute_name, attribute_value| ... }

# File lib/rexml/attlistdecl.rb, line 49
def each(&block)
  @pairs.each(&block)
end
include?(key) click to toggle source

Whether an attlist declaration includes the given attribute definition

if attlist_decl.include? "xmlns:foobar"
# File lib/rexml/attlistdecl.rb, line 43
def include?(key)
  @pairs.keys.include? key
end
node_type() click to toggle source
# File lib/rexml/attlistdecl.rb, line 58
def node_type
  :attlistdecl
end
write(out, indent=-1) click to toggle source

Write out exactly what we got in.

# File lib/rexml/attlistdecl.rb, line 54
def write out, indent=-1
  out << @contents
end


class REXML::Attribute - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Attribute

Defines an Element Attribute; IE, a attribute=value pair, as in: <element attribute=“value”/>. Attributes can be in their own namespaces. General users of REXML will not interact with the Attribute class much.

In Files

  • lib/rexml/attribute.rb

Parent

Object

Included Modules

  • REXML::Node
  • REXML::Namespace

Constants

NEEDS_A_SECOND_CHECK
PATTERN

Attributes

element[R]

The element to which this attribute belongs

normalized[W]

The normalized value of this attribute. That is, the attribute with entities intact.

Public Class Methods

new( first, second=nil, parent=nil ) click to toggle source

Constructor. FIXME: The parser doesn't catch illegal characters in attributes

first

Either: an Attribute, which this new attribute will become a clone of; or a String, which is the name of this attribute

second

If first is an Attribute, then this may be an Element, or nil. If nil, then the Element parent of this attribute is the parent of the first Attribute. If the first argument is a String, then this must also be a String, and is the content of the attribute. If this is the content, it must be fully normalized (contain no illegal characters).

parent

Ignored unless first is a String; otherwise, may be the Element parent of this attribute, or nil.

Attribute.new( attribute_to_clone )
Attribute.new( attribute_to_clone, parent_element )
Attribute.new( "attr", "attr_value" )
Attribute.new( "attr", "attr_value", parent_element )
# File lib/rexml/attribute.rb, line 44
def initialize( first, second=nil, parent=nil )
  @normalized = @unnormalized = @element = nil
  if first.kind_of? Attribute
    self.name = first.expanded_name
    @unnormalized = first.value
    if second.kind_of? Element
      @element = second
    else
      @element = first.element
    end
  elsif first.kind_of? String
    @element = parent
    self.name = first
    @normalized = second.to_s
  else
    raise "illegal argument #{first.class.name} to Attribute constructor"
  end
end

Public Instance Methods

==( other ) click to toggle source

Returns true if other is an Attribute and has the same name and value, false otherwise.

# File lib/rexml/attribute.rb, line 92
def ==( other )
  other.kind_of?(Attribute) and other.name==name and other.value==value
end
clone() click to toggle source

Returns a copy of this attribute

# File lib/rexml/attribute.rb, line 141
def clone
  Attribute.new self
end
doctype() click to toggle source
# File lib/rexml/attribute.rb, line 115
def doctype
  if @element
    doc = @element.document
    doc.doctype if doc
  end
end
element=( element ) click to toggle source

Sets the element of which this object is an attribute. Normally, this is not directly called.

Returns this attribute

# File lib/rexml/attribute.rb, line 149
def element=( element )
  @element = element

  if @normalized
    Text.check( @normalized, NEEDS_A_SECOND_CHECK, doctype )
  end

  self
end
hash() click to toggle source

Creates (and returns) a hash from both the name and value

# File lib/rexml/attribute.rb, line 97
def hash
  name.hash + value.hash
end
inspect() click to toggle source
# File lib/rexml/attribute.rb, line 175
def inspect
  rv = ""
  write( rv )
  rv
end
namespace(arg=nil) click to toggle source

Returns the namespace URL, if defined, or nil otherwise

e = Element.new("el")
e.add_attributes({"xmlns:ns", "http://url"})
e.namespace( "ns" )              # -> "http://url"
# File lib/rexml/attribute.rb, line 85
def namespace arg=nil
  arg = prefix if arg.nil?
  @element.namespace arg
end
node_type() click to toggle source
# File lib/rexml/attribute.rb, line 171
def node_type
  :attribute
end
prefix() click to toggle source

Returns the namespace of the attribute.

e = Element.new( "elns:myelement" )
e.add_attribute( "nsa:a", "aval" )
e.add_attribute( "b", "bval" )
e.attributes.get_attribute( "a" ).prefix   # -> "nsa"
e.attributes.get_attribute( "b" ).prefix   # -> "elns"
a = Attribute.new( "x", "y" )
a.prefix                                   # -> ""
# File lib/rexml/attribute.rb, line 72
def prefix
  pf = super
  if pf == ""
    pf = @element.prefix if @element
  end
  pf
end
remove() click to toggle source

Removes this Attribute from the tree, and returns true if successfull

This method is usually not called directly.

# File lib/rexml/attribute.rb, line 162
def remove
  @element.attributes.delete self.name unless @element.nil?
end
to_s() click to toggle source

Returns the attribute value, with entities replaced

# File lib/rexml/attribute.rb, line 123
def to_s
  return @normalized if @normalized

  @normalized = Text::normalize( @unnormalized, doctype )
  @unnormalized = nil
  @normalized
end
to_string() click to toggle source

Returns this attribute out as XML source, expanding the name

a = Attribute.new( "x", "y" )
a.to_string     # -> "x='y'"
b = Attribute.new( "ns:x", "y" )
b.to_string     # -> "ns:x='y'"
# File lib/rexml/attribute.rb, line 107
def to_string
  if @element and @element.context and @element.context[:attribute_quote] == :quote
    %Q#@expanded_name="#{to_s().gsub(/"/, '&quote;')}"^
  else
    "#@expanded_name='#{to_s().gsub(/'/, '&apos;')}'"
  end
end
value() click to toggle source

Returns the UNNORMALIZED value of this attribute. That is, entities have been expanded to their values

# File lib/rexml/attribute.rb, line 133
def value
  return @unnormalized if @unnormalized
  @unnormalized = Text::unnormalize( @normalized, doctype )
  @normalized = nil
  @unnormalized
end
write( output, indent=-1 ) click to toggle source

Writes this attribute (EG, puts 'key=“value”' to the output)

# File lib/rexml/attribute.rb, line 167
def write( output, indent=-1 )
  output << to_string
end
xpath() click to toggle source
# File lib/rexml/attribute.rb, line 181
def xpath
  path = @element.xpath
  path += "/@#{self.expanded_name}"
  return path
end


class REXML::Attributes - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Attributes

A class that defines the set of Attributes of an Element and provides operations for accessing elements in that set.

In Files

  • lib/rexml/element.rb

Parent

Hash

Public Class Methods

new(element) click to toggle source

Constructor

element

the Element of which this is an Attribute

# File lib/rexml/element.rb, line 971
def initialize element
  @element = element
end

Public Instance Methods

<<( attribute ) click to toggle source
Alias for: add
[](name) click to toggle source

Fetches an attribute value. If you want to get the Attribute itself, use #get_attribute()

name

an XPath attribute name. Namespaces are relevant here.

Returns

the String value of the matching attribute, or nil if no matching attribute was found. This is the unnormalized value (with entities expanded).

doc = Document.new "<a foo:att='1' bar:att='2' att='&lt;'/>"
doc.root.attributes['att']         #-> '<'
doc.root.attributes['bar:att']     #-> '2'
# File lib/rexml/element.rb, line 986
def [](name)
  attr = get_attribute(name)
  return attr.value unless attr.nil?
  return nil
end
[]=( name, value ) click to toggle source

Sets an attribute, overwriting any existing attribute value by the same name. Namespace is significant.

name

the name of the attribute

value

(optional) If supplied, the value of the attribute. If nil, any existing matching attribute is deleted.

Returns

Owning element

doc = Document.new "<a x:foo='1' foo='3'/>"
doc.root.attributes['y:foo'] = '2'
doc.root.attributes['foo'] = '4'
doc.root.attributes['x:foo'] = nil
# File lib/rexml/element.rb, line 1088
def []=( name, value )
  if value.nil?             # Delete the named attribute
    attr = get_attribute(name)
    delete attr
    return
  end

  unless value.kind_of? Attribute
    if @element.document and @element.document.doctype
      value = Text::normalize( value, @element.document.doctype )
    else
      value = Text::normalize( value, nil )
    end
    value = Attribute.new(name, value)
  end
  value.element = @element
  old_attr = fetch(value.name, nil)
  if old_attr.nil?
    store(value.name, value)
  elsif old_attr.kind_of? Hash
    old_attr[value.prefix] = value
  elsif old_attr.prefix != value.prefix
    # Check for conflicting namespaces
    raise ParseException.new(
      "Namespace conflict in adding attribute \"#{value.name}\": "+
      "Prefix \"#{old_attr.prefix}\" = "+
      "\"#{@element.namespace(old_attr.prefix)}\" and prefix "+
      "\"#{value.prefix}\" = \"#{@element.namespace(value.prefix)}\"") if
      value.prefix != "xmlns" and old_attr.prefix != "xmlns" and
      @element.namespace( old_attr.prefix ) ==
        @element.namespace( value.prefix )
      store value.name, { old_attr.prefix   => old_attr,
        value.prefix                => value }
  else
    store value.name, value
  end
  return @element
end
add( attribute ) click to toggle source

Adds an attribute, overriding any existing attribute by the same name. Namespaces are significant.

attribute

An Attribute

# File lib/rexml/element.rb, line 1207
def add( attribute )
  self[attribute.name] = attribute
end
Also aliased as: <<
delete( attribute ) click to toggle source

Removes an attribute

attribute

either a String, which is the name of the attribute to remove – namespaces are significant here – or the attribute to remove.

Returns

the owning element

doc = Document.new "<a y:foo='0' x:foo='1' foo='3' z:foo='4'/>"
doc.root.attributes.delete 'foo'   #-> <a y:foo='0' x:foo='1' z:foo='4'/>"
doc.root.attributes.delete 'x:foo' #-> <a y:foo='0' z:foo='4'/>"
attr = doc.root.attributes.get_attribute('y:foo')
doc.root.attributes.delete attr    #-> <a z:foo='4'/>"
# File lib/rexml/element.rb, line 1175
def delete( attribute )
  name = nil
  prefix = nil
  if attribute.kind_of? Attribute
    name = attribute.name
    prefix = attribute.prefix
  else
    attribute =~ Namespace::NAMESPLIT
    prefix, name = $1, $2
    prefix = '' unless prefix
  end
  old = fetch(name, nil)
  attr = nil
  if old.kind_of? Hash # the supplied attribute is one of many
    attr = old.delete(prefix)
    if old.size == 1
      repl = nil
      old.each_value{|v| repl = v}
      store name, repl
    end
  elsif old.nil?
    return @element
  else # the supplied attribute is a top-level one
    attr = old
    super(name)
  end
  @element
end
delete_all( name ) click to toggle source

Deletes all attributes matching a name. Namespaces are significant.

name

A String; all attributes that match this path will be removed

Returns

an Array of the Attributes that were removed

# File lib/rexml/element.rb, line 1217
def delete_all( name )
  rv = []
  each_attribute { |attribute|
    rv << attribute if attribute.expanded_name == name
  }
  rv.each{ |attr| attr.remove }
  return rv
end
each() { |expanded_name, value| ... } click to toggle source

Iterates over each attribute of an Element, yielding the expanded name and value as a pair of Strings.

doc = Document.new '<a x="1" y="2"/>'
doc.root.attributes.each {|name, value| p name+" => "+value }

# File lib/rexml/element.rb, line 1028
def each
  each_attribute do |attr|
    yield [attr.expanded_name, attr.value]
  end
end
each_attribute() { |attribute| ... } click to toggle source

Iterates over the attributes of an Element. Yields actual Attribute nodes, not String values.

doc = Document.new '<a x="1" y="2"/>'
doc.root.attributes.each_attribute {|attr|
  p attr.expanded_name+" => "+attr.value
}

# File lib/rexml/element.rb, line 1013
def each_attribute # :yields: attribute
  each_value do |val|
    if val.kind_of? Attribute
      yield val
    else
      val.each_value { |atr| yield atr }
    end
  end
end
get_attribute( name ) click to toggle source

Fetches an attribute

name

the name by which to search for the attribute. Can be a prefix:name namespace name.

Returns

The first matching attribute, or nil if there was none. This

value is an Attribute node, not the String value of the attribute.

doc = Document.new '<a x:foo="1" foo="2" bar="3"/>'
doc.root.attributes.get_attribute("foo").value    #-> "2"
doc.root.attributes.get_attribute("x:foo").value  #-> "1"
# File lib/rexml/element.rb, line 1043
def get_attribute( name )
  attr = fetch( name, nil )
  if attr.nil?
    return nil if name.nil?
    # Look for prefix
    name =~ Namespace::NAMESPLIT
    prefix, n = $1, $2
    if prefix
      attr = fetch( n, nil )
      # check prefix
      if attr == nil
      elsif attr.kind_of? Attribute
        return attr if prefix == attr.prefix
      else
        attr = attr[ prefix ]
        return attr
      end
    end
    element_document = @element.document
    if element_document and element_document.doctype
      expn = @element.expanded_name
      expn = element_document.doctype.name if expn.size == 0
      attr_val = element_document.doctype.attribute_of(expn, name)
      return Attribute.new( name, attr_val ) if attr_val
    end
    return nil
  end
  if attr.kind_of? Hash
    attr = attr[ @element.prefix ]
  end
  return attr
end
get_attribute_ns(namespace, name) click to toggle source

The get_attribute_ns method retrieves a method by its namespace and name. Thus it is possible to reliably identify an attribute even if an XML processor has changed the prefix.

Method contributed by Henrik Martensson

# File lib/rexml/element.rb, line 1231
def get_attribute_ns(namespace, name)
  result = nil
  each_attribute() { |attribute|
    if name == attribute.name &&
      namespace == attribute.namespace() &&
      ( !namespace.empty? || !attribute.fully_expanded_name.index(':') )
      # foo will match xmlns:foo, but only if foo isn't also an attribute
      result = attribute if !result or !namespace.empty? or
                            !attribute.fully_expanded_name.index(':')
    end
  }
  result
end
length() click to toggle source

Returns the number of attributes the owning Element contains.

doc = Document "<a x='1' y='2' foo:x='3'/>"
doc.root.attributes.length        #-> 3
# File lib/rexml/element.rb, line 999
def length
  c = 0
  each_attribute { c+=1 }
  c
end
Also aliased as: size
namespaces() click to toggle source
# File lib/rexml/element.rb, line 1149
def namespaces
  namespaces = {}
  each_attribute do |attribute|
    namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
  end
  if @element.document and @element.document.doctype
    expn = @element.expanded_name
    expn = @element.document.doctype.name if expn.size == 0
    @element.document.doctype.attributes_of(expn).each {
      |attribute|
      namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
    }
  end
  namespaces
end
prefixes() click to toggle source

Returns an array of Strings containing all of the prefixes declared by this set of # attributes. The array does not include the default namespace declaration, if one exists.

doc = Document.new("<a xmlns='foo' xmlns:x='bar' xmlns:y='twee' "+
      "z='glorp' p:k='gru'/>")
prefixes = doc.root.attributes.prefixes    #-> ['x', 'y']
# File lib/rexml/element.rb, line 1133
def prefixes
  ns = []
  each_attribute do |attribute|
    ns << attribute.name if attribute.prefix == 'xmlns'
  end
  if @element.document and @element.document.doctype
    expn = @element.expanded_name
    expn = @element.document.doctype.name if expn.size == 0
    @element.document.doctype.attributes_of(expn).each {
      |attribute|
      ns << attribute.name if attribute.prefix == 'xmlns'
    }
  end
  ns
end
size() click to toggle source
Alias for: length
to_a() click to toggle source
# File lib/rexml/element.rb, line 992
def to_a
  values.flatten
end


class REXML::CData - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::CData

In Files

  • lib/rexml/cdata.rb

Parent

Text

Constants

ILLEGAL
START
STOP

Public Class Methods

new( first, whitespace=true, parent=nil ) click to toggle source
Constructor.  CData is data between <![CDATA[ ... ]]>

Examples

CData.new( source )
CData.new( "Here is some CDATA" )
CData.new( "Some unprocessed data", respect_whitespace_TF, parent_element )
# File lib/rexml/cdata.rb, line 15
def initialize( first, whitespace=true, parent=nil )
  super( first, whitespace, parent, false, true, ILLEGAL )
end

Public Instance Methods

clone() click to toggle source

Make a copy of this object

Examples

c = CData.new( "Some text" )
d = c.clone
d.to_s        # -> "Some text"
# File lib/rexml/cdata.rb, line 25
def clone
  CData.new self
end
to_s() click to toggle source

Returns the content of this CData object

Examples

c = CData.new( "Some text" )
c.to_s        # -> "Some text"
# File lib/rexml/cdata.rb, line 34
def to_s
  @string
end
value() click to toggle source
# File lib/rexml/cdata.rb, line 38
def value
  @string
end
write( output=$stdout, indent=-1, transitive=false, ie_hack=false ) click to toggle source

DEPRECATED

See the rexml/formatters package

Generates XML output of this object

output

Where to write the string. Defaults to $stdout

indent

The amount to indent this node by

transitive

Ignored

ie_hack

Ignored

Examples

c = CData.new( " Some text " )
c.write( $stdout )     #->  <![CDATA[ Some text ]]>
# File lib/rexml/cdata.rb, line 59
def write( output=$stdout, indent=-1, transitive=false, ie_hack=false )
  Kernel.warn( "#{self.class.name}.write is deprecated" )
  indent( output, indent )
  output << START
  output << @string
  output << STOP
end


class REXML::Child - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Child

A Child object is something contained by a parent, and this class contains methods to support that. Most user code will not use this class directly.

In Files

  • lib/rexml/child.rb

Parent

Object

Included Modules

  • REXML::Node

Attributes

parent[R]

Public Class Methods

new( parent = nil ) click to toggle source

Constructor. Any inheritors of this class should call super to make sure this method is called.

parent

if supplied, the parent of this child will be set to the supplied value, and self will be added to the parent

# File lib/rexml/child.rb, line 17
def initialize( parent = nil )
  @parent = nil
  # Declare @parent, but don't define it.  The next line sets the
  # parent.
  parent.add( self ) if parent
end

Public Instance Methods

bytes() click to toggle source

This doesn't yet handle encodings

# File lib/rexml/child.rb, line 90
def bytes
  document.encoding

  to_s
end
document() click to toggle source
Returns

the document this child belongs to, or nil if this child

belongs to no document

# File lib/rexml/child.rb, line 84
def document
  return parent.document unless parent.nil?
  nil
end
next_sibling=( other ) click to toggle source

Sets the next sibling of this child. This can be used to insert a child after some other child.

a = Element.new("a")
b = a.add_element("b")
c = Element.new("c")
b.next_sibling = c
# => <a><b/><c/></a>

# File lib/rexml/child.rb, line 67
def next_sibling=( other )
  parent.insert_after self, other
end
parent=( other ) click to toggle source

Sets the parent of this child to the supplied argument.

other

Must be a Parent object. If this object is the same object as the existing parent of this child, no action is taken. Otherwise, this child is removed from the current parent (if one exists), and is added to the new parent.

Returns

The parent added

# File lib/rexml/child.rb, line 51
def parent=( other )
  return @parent if @parent == other
  @parent.delete self if defined? @parent and @parent
  @parent = other
end
previous_sibling=(other) click to toggle source

Sets the previous sibling of this child. This can be used to insert a child before some other child.

a = Element.new("a")
b = a.add_element("b")
c = Element.new("c")
b.previous_sibling = c
# => <a><b/><c/></a>

# File lib/rexml/child.rb, line 78
def previous_sibling=(other)
  parent.insert_before self, other
end
remove() click to toggle source

Removes this child from the parent.

Returns

self

# File lib/rexml/child.rb, line 36
def remove
  unless @parent.nil?
    @parent.delete self
  end
  self
end
replace_with( child ) click to toggle source

Replaces this object with another object. Basically, calls REXML::Parent#replace_child

Returns

self

# File lib/rexml/child.rb, line 28
def replace_with( child )
  @parent.replace_child( self, child )
  self
end


class REXML::Comment - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Comment

Represents an XML comment; that is, text between <!– … –>

In Files

  • lib/rexml/comment.rb

Parent

REXML::Child

Included Modules

  • Comparable

Constants

START
STOP

Attributes

string[RW]

The content text

to_s[RW]

The content text

Public Class Methods

new( first, second = nil ) click to toggle source

Constructor. The first argument can be one of three types: @param first If String, the contents of this comment are set to the argument. If Comment, the argument is duplicated. If Source, the argument is scanned for a comment. @param second If the first argument is a Source, this argument should be nil, not supplied, or a Parent to be set as the parent of this object

# File lib/rexml/comment.rb, line 23
def initialize( first, second = nil )
  #puts "IN COMMENT CONSTRUCTOR; SECOND IS #{second.type}"
  super(second)
  if first.kind_of? String
    @string = first
  elsif first.kind_of? Comment
    @string = first.string
  end
end

Public Instance Methods

<=>(other) click to toggle source

Compares this Comment to another; the contents of the comment are used in the comparison.

# File lib/rexml/comment.rb, line 63
def <=>(other)
  other.to_s <=> @string
end
==( other ) click to toggle source

Compares this Comment to another; the contents of the comment are used in the comparison.

# File lib/rexml/comment.rb, line 70
def ==( other )
  other.kind_of? Comment and
  (other <=> self) == 0
end
clone() click to toggle source
# File lib/rexml/comment.rb, line 33
def clone
  Comment.new self
end
node_type() click to toggle source
# File lib/rexml/comment.rb, line 75
def node_type
  :comment
end
write( output, indent=-1, transitive=false, ie_hack=false ) click to toggle source

DEPRECATED

See REXML::Formatters

output

Where to write the string

indent

An integer. If -1, no indenting will be used; otherwise, the indentation will be this number of spaces, and children will be indented an additional amount.

transitive

Ignored by this class. The contents of comments are never modified.

ie_hack

Needed for conformity to the child API, but not used by this class.

# File lib/rexml/comment.rb, line 50
def write( output, indent=-1, transitive=false, ie_hack=false )
  Kernel.warn("Comment.write is deprecated.  See REXML::Formatters")
  indent( output, indent )
  output << START
  output << @string
  output << STOP
end


module REXML::DTD - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::DTD

In Files

  • lib/rexml/dtd/attlistdecl.rb
  • lib/rexml/dtd/dtd.rb
  • lib/rexml/dtd/elementdecl.rb
  • lib/rexml/dtd/entitydecl.rb
  • lib/rexml/dtd/notationdecl.rb


class REXML::DTD::AttlistDecl - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::DTD::AttlistDecl

In Files

  • lib/rexml/dtd/attlistdecl.rb

Parent

REXML::Child

Constants

PATTERN_RE
START
START_RE


class REXML::DTD::ElementDecl - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::DTD::ElementDecl

In Files

  • lib/rexml/dtd/elementdecl.rb

Parent

REXML::Child

Constants

PATTERN_RE
START
START_RE

Public Class Methods

new(match) click to toggle source

s*(((([“‘]).*?5)|[^/’”>]*)*?)(/)?>/um, true)

# File lib/rexml/dtd/elementdecl.rb, line 11
def initialize match
  @name = match[1]
  @rest = match[2]
end


class REXML::DTD::EntityDecl - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::DTD::EntityDecl

In Files

  • lib/rexml/dtd/entitydecl.rb

Parent

REXML::Child

Constants

PERCENT
PLAIN
PUBLIC
START
START_RE
SYSTEM

Public Class Methods

new(src) click to toggle source

<!ENTITY name SYSTEM “…”> <!ENTITY name “…”>

# File lib/rexml/dtd/entitydecl.rb, line 13
def initialize src
  super()
  md = nil
  if src.match( PUBLIC )
    md = src.match( PUBLIC, true )
    @middle = "PUBLIC"
    @content = "#{md[2]} #{md[4]}"
  elsif src.match( SYSTEM )
    md = src.match( SYSTEM, true )
    @middle = "SYSTEM"
    @content = md[2]
  elsif src.match( PLAIN )
    md = src.match( PLAIN, true )
    @middle = ""
    @content = md[2]
  elsif src.match( PERCENT )
    md = src.match( PERCENT, true )
    @middle = ""
    @content = md[2]
  end
  raise ParseException.new("failed Entity match", src) if md.nil?
  @name = md[1]
end
parse_source(source, listener) click to toggle source
# File lib/rexml/dtd/entitydecl.rb, line 49
def EntityDecl.parse_source source, listener
  md = source.match( PATTERN_RE, true )
  thing = md[0].squeeze(" \t\n\r")
  listener.send inspect.downcase, thing
end

Public Instance Methods

to_s() click to toggle source
# File lib/rexml/dtd/entitydecl.rb, line 37
def to_s
  rv = "<!ENTITY #@name "
  rv << "#@middle " if @middle.size > 0
  rv << @content
  rv
end
write( output, indent ) click to toggle source
# File lib/rexml/dtd/entitydecl.rb, line 44
def write( output, indent )
  indent( output, indent )
  output << to_s
end


class REXML::DTD::NotationDecl - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::DTD::NotationDecl

In Files

  • lib/rexml/dtd/notationdecl.rb

Parent

REXML::Child

Constants

PUBLIC
START
START_RE
SYSTEM

Public Class Methods

new(src) click to toggle source
# File lib/rexml/dtd/notationdecl.rb, line 9
def initialize src
  super()
  if src.match( PUBLIC )
    md = src.match( PUBLIC, true )
  elsif src.match( SYSTEM )
    md = src.match( SYSTEM, true )
  else
    raise ParseException.new( "error parsing notation: no matching pattern", src )
  end
  @name = md[1]
  @middle = md[2]
  @rest = md[3]
end
parse_source(source, listener) click to toggle source
# File lib/rexml/dtd/notationdecl.rb, line 32
def NotationDecl.parse_source source, listener
  md = source.match( PATTERN_RE, true )
  thing = md[0].squeeze(" \t\n\r")
  listener.send inspect.downcase, thing
end

Public Instance Methods

to_s() click to toggle source
# File lib/rexml/dtd/notationdecl.rb, line 23
def to_s
  "<!NOTATION #@name #@middle #@rest>"
end
write( output, indent ) click to toggle source
# File lib/rexml/dtd/notationdecl.rb, line 27
def write( output, indent )
  indent( output, indent )
  output << to_s
end


class REXML::DTD::Parser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::DTD::Parser

In Files

  • lib/rexml/dtd/dtd.rb

Parent

Object

Public Class Methods

parse( input ) click to toggle source
# File lib/rexml/dtd/dtd.rb, line 11
def Parser.parse( input )
  case input
  when String
    parse_helper input
  when File
    parse_helper input.read
  end
end
parse_helper( input ) click to toggle source

Takes a String and parses it out

# File lib/rexml/dtd/dtd.rb, line 21
def Parser.parse_helper( input )
  contents = Parent.new
  while input.size > 0
    case input
    when ElementDecl.PATTERN_RE
      match = $&
      source = $'
      contents << ElementDecl.new( match )
    when AttlistDecl.PATTERN_RE
      matchdata = $~
      source = $'
      contents << AttlistDecl.new( matchdata )
    when EntityDecl.PATTERN_RE
      matchdata = $~
      source = $'
      contents << EntityDecl.new( matchdata )
    when Comment.PATTERN_RE
      matchdata = $~
      source = $'
      contents << Comment.new( matchdata )
    when NotationDecl.PATTERN_RE
      matchdata = $~
      source = $'
      contents << NotationDecl.new( matchdata )
    end
  end
  contents
end


class REXML::Declaration - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Declaration

This is an abstract class. You never use this directly; it serves as a parent class for the specific declarations.

In Files

  • lib/rexml/doctype.rb

Parent

REXML::Child

Public Class Methods

new(src) click to toggle source
# File lib/rexml/doctype.rb, line 203
def initialize src
  super()
  @string = src
end

Public Instance Methods

to_s() click to toggle source
# File lib/rexml/doctype.rb, line 208
def to_s
  @string+'>'
end
write( output, indent ) click to toggle source

DEPRECATED

See REXML::Formatters

# File lib/rexml/doctype.rb, line 215
def write( output, indent )
  output << to_s
end


class REXML::DocType - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::DocType

Represents an XML DOCTYPE declaration; that is, the contents of <!DOCTYPE … >. DOCTYPES can be used to declare the DTD of a document, as well as being used to declare entities used in the document.

In Files

  • lib/rexml/doctype.rb

Parent

Parent

Included Modules

  • REXML::XMLTokens

Constants

DEFAULT_ENTITIES
PUBLIC
START
STOP
SYSTEM

Attributes

entities[R]

name is the name of the doctype #external_id is the referenced DTD, if given

external_id[R]

name is the name of the doctype #external_id is the referenced DTD, if given

name[R]

name is the name of the doctype #external_id is the referenced DTD, if given

namespaces[R]

name is the name of the doctype #external_id is the referenced DTD, if given

Public Class Methods

new( first, parent=nil ) click to toggle source

Constructor

dt = DocType.new( 'foo', '-//I/Hate/External/IDs' )
# <!DOCTYPE foo '-//I/Hate/External/IDs'>
dt = DocType.new( doctype_to_clone )
# Incomplete.  Shallow clone of doctype

Note that the constructor:

Doctype.new( Source.new( "<!DOCTYPE foo 'bar'>" ) )

is deprecated. Do not use it. It will probably disappear.

# File lib/rexml/doctype.rb, line 41
def initialize( first, parent=nil )
  @entities = DEFAULT_ENTITIES
  @long_name = @uri = nil
  if first.kind_of? String
    super()
    @name = first
    @external_id = parent
  elsif first.kind_of? DocType
    super( parent )
    @name = first.name
    @external_id = first.external_id
  elsif first.kind_of? Array
    super( parent )
    @name = first[0]
    @external_id = first[1]
    @long_name = first[2]
    @uri = first[3]
  elsif first.kind_of? Source
    super( parent )
    parser = Parsers::BaseParser.new( first )
    event = parser.pull
    if event[0] == :start_doctype
      @name, @external_id, @long_name, @uri, = event[1..-1]
    end
  else
    super()
  end
end

Public Instance Methods

add(child) click to toggle source
# File lib/rexml/doctype.rb, line 136
def add child
  super(child)
  @entities = DEFAULT_ENTITIES.clone if @entities == DEFAULT_ENTITIES
  @entities[ child.name ] = child if child.kind_of? Entity
end
attribute_of(element, attribute) click to toggle source
# File lib/rexml/doctype.rb, line 84
def attribute_of element, attribute
  att_decl = find do |child|
    child.kind_of? AttlistDecl and
    child.element_name == element and
    child.include? attribute
  end
  return nil unless att_decl
  att_decl[attribute]
end
attributes_of(element) click to toggle source
# File lib/rexml/doctype.rb, line 74
def attributes_of element
  rv = []
  each do |child|
    child.each do |key,val|
      rv << Attribute.new(key,val)
    end if child.kind_of? AttlistDecl and child.element_name == element
  end
  rv
end
clone() click to toggle source
# File lib/rexml/doctype.rb, line 94
def clone
  DocType.new self
end
context() click to toggle source
# File lib/rexml/doctype.rb, line 128
def context
  @parent.context
end
entity( name ) click to toggle source
# File lib/rexml/doctype.rb, line 132
def entity( name )
  @entities[name].unnormalized if @entities[name]
end
node_type() click to toggle source
# File lib/rexml/doctype.rb, line 70
def node_type
  :doctype
end
notation(name) click to toggle source

Retrieves a named notation. Only notations declared in the internal DTD subset can be retrieved.

Method contributed by Henrik Martensson

# File lib/rexml/doctype.rb, line 180
def notation(name)
  notations.find { |notation_decl|
    notation_decl.name == name
  }
end
notations() click to toggle source

This method returns a list of notations that have been declared in the internal DTD subset. Notations in the external DTD subset are not listed.

Method contributed by Henrik Martensson

# File lib/rexml/doctype.rb, line 172
def notations
  children().select {|node| node.kind_of?(REXML::NotationDecl)}
end
public() click to toggle source

This method retrieves the public identifier identifying the document's DTD.

Method contributed by Henrik Martensson

# File lib/rexml/doctype.rb, line 146
def public
  case @external_id
  when "SYSTEM"
    nil
  when "PUBLIC"
    strip_quotes(@long_name)
  end
end
system() click to toggle source

This method retrieves the system identifier identifying the document's DTD

Method contributed by Henrik Martensson

# File lib/rexml/doctype.rb, line 158
def system
  case @external_id
  when "SYSTEM"
    strip_quotes(@long_name)
  when "PUBLIC"
    @uri.kind_of?(String) ? strip_quotes(@uri) : nil
  end
end
write( output, indent=0, transitive=false, ie_hack=false ) click to toggle source
output

Where to write the string

indent

An integer. If -1, no indentation will be used; otherwise, the indentation will be this number of spaces, and children will be indented an additional amount.

transitive

Ignored

ie_hack

Ignored

# File lib/rexml/doctype.rb, line 108
def write( output, indent=0, transitive=false, ie_hack=false )
  f = REXML::Formatters::Default.new
  indent( output, indent )
  output << START
  output << ' '
  output << @name
  output << " #@external_id" if @external_id
  output << " #{@long_name.inspect}" if @long_name
  output << " #{@uri.inspect}" if @uri
  unless @children.empty?
    output << ' ['
    @children.each { |child|
      output << "\n"
      f.write( child, output )
    }
    output << "\n]"
  end
  output << STOP
end


class REXML::Document - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Document

Represents a full XML document, including PIs, a doctype, etc. A Document has a single child that can be accessed by root(). Note that if you want to have an XML declaration written for a document you create, you must add one; REXML documents do not write a default declaration for you. See |DECLARATION| and |write|.

In Files

  • lib/rexml/document.rb

Parent

Element

Constants

DECLARATION

A convenient default XML declaration. If you want an XML declaration, the easiest way to add one is mydoc << Document::DECLARATION DEPRECATED Use: mydoc << REXML::XMLDecl.default

Attributes

entity_expansion_count[R]

Public Class Methods

entity_expansion_limit() click to toggle source

Get the entity expansion limit. By default the limit is set to 10000.

# File lib/rexml/document.rb, line 254
def Document::entity_expansion_limit
  return @@entity_expansion_limit
end
entity_expansion_limit=( val ) click to toggle source

Set the entity expansion limit. By default the limit is set to 10000.

# File lib/rexml/document.rb, line 249
def Document::entity_expansion_limit=( val )
  @@entity_expansion_limit = val
end
entity_expansion_text_limit() click to toggle source

Get the entity expansion limit. By default the limit is set to 10240.

Deprecated. Use REXML.entity_expansion_text_limit instead.

# File lib/rexml/document.rb, line 268
def Document::entity_expansion_text_limit
  return REXML.entity_expansion_text_limit
end
entity_expansion_text_limit=( val ) click to toggle source

Set the entity expansion limit. By default the limit is set to 10240.

Deprecated. Use REXML.entity_expansion_text_limit= instead.

# File lib/rexml/document.rb, line 261
def Document::entity_expansion_text_limit=( val )
  REXML.entity_expansion_text_limit = val
end
new( source = nil, context = {} ) click to toggle source

Constructor @param source if supplied, must be a Document, String, or IO. Documents have their context and Element attributes cloned. Strings are expected to be valid XML documents. IOs are expected to be sources of valid XML documents. @param context if supplied, contains the context of the document; this should be a Hash.

# File lib/rexml/document.rb, line 34
def initialize( source = nil, context = {} )
  @entity_expansion_count = 0
  super()
  @context = context
  return if source.nil?
  if source.kind_of? Document
    @context = source.context
    super source
  else
    build(  source )
  end
end
parse_stream( source, listener ) click to toggle source
# File lib/rexml/document.rb, line 242
def Document::parse_stream( source, listener )
  Parsers::StreamParser.new( source, listener ).parse
end

Public Instance Methods

<<( child ) click to toggle source
Alias for: add
add( child ) click to toggle source

We override this, because XMLDecls and DocTypes must go at the start of the document

# File lib/rexml/document.rb, line 67
def add( child )
  if child.kind_of? XMLDecl
    if @children[0].kind_of? XMLDecl
      @children[0] = child
    else
      @children.unshift child
    end
    child.parent = self
  elsif child.kind_of? DocType
    # Find first Element or DocType node and insert the decl right
    # before it.  If there is no such node, just insert the child at the
    # end.  If there is a child and it is an DocType, then replace it.
    insert_before_index = @children.find_index { |x|
      x.kind_of?(Element) || x.kind_of?(DocType)
    }
    if insert_before_index # Not null = not end of list
      if @children[ insert_before_index ].kind_of? DocType
        @children[ insert_before_index ] = child
      else
        @children[ insert_before_index-1, 0 ] = child
      end
    else  # Insert at end of list
      @children << child
    end
    child.parent = self
  else
    rv = super
    raise "attempted adding second root element to document" if @elements.size > 1
    rv
  end
end
Also aliased as: <<
add_element(arg=nil, arg2=nil) click to toggle source
# File lib/rexml/document.rb, line 100
def add_element(arg=nil, arg2=nil)
  rv = super
  raise "attempted adding second root element to document" if @elements.size > 1
  rv
end
clone() click to toggle source

Should be obvious

# File lib/rexml/document.rb, line 52
def clone
  Document.new self
end
doctype() click to toggle source

@return the DocType child of the document, if one exists, and nil otherwise.

# File lib/rexml/document.rb, line 116
def doctype
  @children.find { |item| item.kind_of? DocType }
end
encoding() click to toggle source

@return the XMLDecl encoding of this document as an Encoding object. If no XMLDecl has been set, returns the default encoding.

# File lib/rexml/document.rb, line 137
def encoding
  xml_decl().encoding
end
expanded_name() click to toggle source

According to the XML spec, a root node has no expanded name

# File lib/rexml/document.rb, line 57
def expanded_name
  ''
  #d = doc_type
  #d ? d.name : "UNDEFINED"
end
Also aliased as: name
name() click to toggle source
Alias for: expanded_name
node_type() click to toggle source
# File lib/rexml/document.rb, line 47
def node_type
  :document
end
record_entity_expansion() click to toggle source
# File lib/rexml/document.rb, line 274
def record_entity_expansion
  @entity_expansion_count += 1
  if @entity_expansion_count > @@entity_expansion_limit
    raise "number of entity expansions exceeded, processing aborted."
  end
end
root() click to toggle source

@return the root Element of the document, or nil if this document has no children.

# File lib/rexml/document.rb, line 108
def root
  elements[1]
  #self
  #@children.find { |item| item.kind_of? Element }
end
stand_alone?() click to toggle source

@return the XMLDecl standalone value of this document as a String. If no XMLDecl has been set, returns the default setting.

# File lib/rexml/document.rb, line 143
def stand_alone?
  xml_decl().stand_alone?
end
version() click to toggle source

@return the XMLDecl version of this document as a String. If no XMLDecl has been set, returns the default version.

# File lib/rexml/document.rb, line 130
def version
  xml_decl().version
end
write(output=$stdout, indent=-1, transtive=false, ie_hack=false, encoding=nil) click to toggle source
write(options={:output => $stdout, :indent => -1, :transtive => false, :ie_hack => false, :encoding → nil})

Write the XML tree out, optionally with indent. This writes out the entire XML document, including XML declarations, doctype declarations, and processing instructions (if any are given).

A controversial point is whether Document should always write the XML declaration (<?xml version='1.0'?>) whether or not one is given by the user (or source document). REXML does not write one if one was not specified, because it adds unnecessary bandwidth to applications such as XML-RPC.

Accept Nth argument style and options Hash style as argument. The recommended style is options Hash style for one or more arguments case.

Examples

Document.new("<a><b/></a>").write

output = ""
Document.new("<a><b/></a>").write(output)

output = ""
Document.new("<a><b/></a>").write(:output => output, :indent => 2)

See also the classes in the rexml/formatters package for the proper way to change the default formatting of XML output.

Examples

output = ""
tr = Transitive.new
tr.write(Document.new("<a><b/></a>"), output)
output

output an object which supports '<< string'; this is where the document will be written.

indent

An integer. If -1, no indenting will be used; otherwise, the indentation will be twice this number of spaces, and children will be indented an additional amount. For a value of 3, every item will be indented 3 more levels, or 6 more spaces (2 * 3). Defaults to -1

transitive

If transitive is true and indent is >= 0, then the output will be pretty-printed in such a way that the added whitespace does not affect the absolute value of the document – that is, it leaves the value and number of Text nodes in the document unchanged.

ie_hack

Internet Explorer is the worst piece of crap to have ever been written, with the possible exception of Windows itself. Since IE is unable to parse proper XML, we have to provide a hack to generate XML that IE's limited abilities can handle. This hack inserts a space before the /> on empty tags. Defaults to false

encoding

Encoding name as String. Change output encoding to specified encoding instead of encoding in XML declaration. Defaults to nil. It means encoding in XML declaration is used.

# File lib/rexml/document.rb, line 206
def write(*arguments)
  if arguments.size == 1 and arguments[0].class == Hash
    options = arguments[0]

    output     = options[:output]
    indent     = options[:indent]
    transitive = options[:transitive]
    ie_hack    = options[:ie_hack]
    encoding   = options[:encoding]
  else
    output, indent, transitive, ie_hack, encoding, = *arguments
  end

  output   ||= $stdout
  indent   ||= -1
  transitive = false if transitive.nil?
  ie_hack    = false if ie_hack.nil?
  encoding ||= xml_decl.encoding

  if encoding != 'UTF-8' && !output.kind_of?(Output)
    output = Output.new( output, encoding )
  end
  formatter = if indent > -1
      if transitive
        require "rexml/formatters/transitive"
        REXML::Formatters::Transitive.new( indent, ie_hack )
      else
        REXML::Formatters::Pretty.new( indent, ie_hack )
      end
    else
      REXML::Formatters::Default.new( ie_hack )
    end
  formatter.write( self, output )
end
xml_decl() click to toggle source

@return the XMLDecl of this document; if no XMLDecl has been set, the default declaration is returned.

# File lib/rexml/document.rb, line 122
def xml_decl
  rv = @children[0]
  return rv if rv.kind_of? XMLDecl
  rv = @children.unshift(XMLDecl.default)[0]
end


class REXML::Element - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Element

Represents a tagged XML element. Elements are characterized by having children, attributes, and names, and can themselves be children.

In Files

  • lib/rexml/element.rb

Parent

Parent

Included Modules

  • REXML::Namespace

Constants

UNDEFINED

Attributes

attributes[R]

Mechanisms for accessing attributes and child elements of this element.

context[RW]

The context holds information about the processing environment, such as whitespace handling.

elements[R]

Mechanisms for accessing attributes and child elements of this element.

Public Class Methods

new( arg = UNDEFINED, parent=nil, context=nil ) click to toggle source

Constructor

arg

if not supplied, will be set to the default value. If a String, the name of this object will be set to the argument. If an Element, the object will be shallowly cloned; name, attributes, and namespaces will be copied. Children will not be copied.

parent

if supplied, must be a Parent, and will be used as the parent of this object.

context

If supplied, must be a hash containing context items. Context items include:

  • :respect_whitespace the value of this is :all or an array of strings being the names of the elements to respect whitespace for. Defaults to :all.

  • :compress_whitespace the value can be :all or an array of strings being the names of the elements to ignore whitespace on. Overrides :respect_whitespace.

  • :ignore_whitespace_nodes the value can be :all or an array of strings being the names of the elements in which to ignore whitespace-only nodes. If this is set, Text nodes which contain only whitespace will not be added to the document tree.

  • :raw can be :all, or an array of strings being the names of the elements to process in raw mode. In raw mode, special characters in text is not converted to or from entities.

# File lib/rexml/element.rb, line 58
def initialize( arg = UNDEFINED, parent=nil, context=nil )
  super(parent)

  @elements = Elements.new(self)
  @attributes = Attributes.new(self)
  @context = context

  if arg.kind_of? String
    self.name = arg
  elsif arg.kind_of? Element
    self.name = arg.expanded_name
    arg.attributes.each_attribute{ |attribute|
      @attributes << Attribute.new( attribute )
    }
    @context = arg.context
  end
end

Public Instance Methods

add_attribute( key, value=nil ) click to toggle source

Adds an attribute to this element, overwriting any existing attribute by the same name.

key

can be either an Attribute or a String. If an Attribute, the attribute is added to the list of Element attributes. If String, the argument is used as the name of the new attribute, and the value parameter must be supplied.

value

Required if key is a String, and ignored if the first argument is an Attribute. This is a String, and is used as the value of the new Attribute. This should be the unnormalized value of the attribute (without entities).

Returns

the Attribute added

e = Element.new 'e'
e.add_attribute( 'a', 'b' )               #-> <e a='b'/>
e.add_attribute( 'x:a', 'c' )             #-> <e a='b' x:a='c'/>
e.add_attribute Attribute.new('b', 'd')   #-> <e a='b' x:a='c' b='d'/>
# File lib/rexml/element.rb, line 599
def add_attribute( key, value=nil )
  if key.kind_of? Attribute
    @attributes << key
  else
    @attributes[key] = value
  end
end
add_attributes(hash) click to toggle source

Add multiple attributes to this element.

hash

is either a hash, or array of arrays

el.add_attributes( {"name1"=>"value1", "name2"=>"value2"} )
el.add_attributes( [ ["name1","value1"], ["name2"=>"value2"] ] )

# File lib/rexml/element.rb, line 611
def add_attributes hash
  if hash.kind_of? Hash
    hash.each_pair {|key, value| @attributes[key] = value }
  elsif hash.kind_of? Array
    hash.each { |value| @attributes[ value[0] ] = value[1] }
  end
end
add_element(element, attrs=nil) click to toggle source

Adds a child to this element, optionally setting attributes in the element.

element

optional. If Element, the element is added. Otherwise, a new Element is constructed with the argument (see Element.initialize).

attrs

If supplied, must be a Hash containing String name,value pairs, which will be used to set the attributes of the new Element.

Returns

the Element that was added

el = doc.add_element 'my-tag'
el = doc.add_element 'my-tag', {'attr1'=>'val1', 'attr2'=>'val2'}
el = Element.new 'my-tag'
doc.add_element el

# File lib/rexml/element.rb, line 295
def add_element element, attrs=nil
  raise "First argument must be either an element name, or an Element object" if element.nil?
  el = @elements.add(element)
  attrs.each do |key, value|
    el.attributes[key]=value
  end       if attrs.kind_of? Hash
  el
end
add_namespace( prefix, uri=nil ) click to toggle source

Adds a namespace to this element.

prefix

the prefix string, or the namespace URI if uri is not supplied

uri

the namespace URI. May be nil, in which prefix is used as the URI

Evaluates to: this Element

a = Element.new("a")
a.add_namespace("xmlns:foo", "bar" )
a.add_namespace("foo", "bar")  # shorthand for previous line
a.add_namespace("twiddle")
puts a   #-> <a xmlns:foo='bar' xmlns='twiddle'/>
# File lib/rexml/element.rb, line 250
def add_namespace( prefix, uri=nil )
  unless uri
    @attributes["xmlns"] = prefix
  else
    prefix = "xmlns:#{prefix}" unless prefix =~ /^xmlns:/
    @attributes[ prefix ] = uri
  end
  self
end
add_text( text ) click to toggle source

A helper method to add a Text child. Actual Text instances can be added with regular Parent methods, such as add() and <<()

text

if a String, a new Text instance is created and added to the parent. If Text, the object is added directly.

Returns

this Element

e = Element.new('a')          #-> <e/>
e.add_text 'foo'              #-> <e>foo</e>
e.add_text Text.new(' bar')    #-> <e>foo bar</e>

Note that at the end of this example, the branch has 3 nodes; the 'e' element and 2 Text node children.

# File lib/rexml/element.rb, line 522
def add_text( text )
  if text.kind_of? String
    if @children[-1].kind_of? Text
      @children[-1] << text
      return
    end
    text = Text.new( text, whitespace(), nil, raw() )
  end
  self << text unless text.nil?
  return self
end
attribute( name, namespace=nil ) click to toggle source

Attributes #

# File lib/rexml/element.rb, line 553
def attribute( name, namespace=nil )
  prefix = nil
  if namespaces.respond_to? :key
    prefix = namespaces.key(namespace) if namespace
  else
    prefix = namespaces.index(namespace) if namespace
  end
  prefix = nil if prefix == 'xmlns'

  ret_val =
    attributes.get_attribute( "#{prefix ? prefix + ':' : ''}#{name}" )

  return ret_val unless ret_val.nil?
  return nil if prefix.nil?

  # now check that prefix'es namespace is not the same as the
  # default namespace
  return nil unless ( namespaces[ prefix ] == namespaces[ 'xmlns' ] )

  attributes.get_attribute( name )

end
cdatas() click to toggle source

Get an array of all CData children. IMMUTABLE

# File lib/rexml/element.rb, line 643
def cdatas
  find_all { |child| child.kind_of? CData }.freeze
end
clone() click to toggle source

Creates a shallow copy of self.

d = Document.new "<a><b/><b/><c><d/></c></a>"
new_a = d.root.clone
puts new_a  # => "<a/>"

# File lib/rexml/element.rb, line 96
def clone
  self.class.new self
end
comments() click to toggle source

Get an array of all Comment children. IMMUTABLE

# File lib/rexml/element.rb, line 649
def comments
  find_all { |child| child.kind_of? Comment }.freeze
end
delete_attribute(key) click to toggle source

Removes an attribute

key

either an Attribute or a String. In either case, the attribute is found by matching the attribute name to the argument, and then removed. If no attribute is found, no action is taken.

Returns

the attribute removed, or nil if this Element did not contain a matching attribute

e = Element.new('E')
e.add_attribute( 'name', 'Sean' )             #-> <E name='Sean'/>
r = e.add_attribute( 'sur:name', 'Russell' )  #-> <E name='Sean' sur:name='Russell'/>
e.delete_attribute( 'name' )                  #-> <E sur:name='Russell'/>
e.delete_attribute( r )                       #-> <E/>
# File lib/rexml/element.rb, line 632
def delete_attribute(key)
  attr = @attributes.get_attribute(key)
  attr.remove unless attr.nil?
end
delete_element(element) click to toggle source

Deletes a child element.

element

Must be an Element, String, or Integer. If Element, the element is removed. If String, the element is found (via XPath) and removed. <em>This means that any parent can remove any descendant.<em> If Integer, the Element indexed by that number will be removed.

Returns

the element that was removed.

doc.delete_element "/a/b/c[@id='4']"
doc.delete_element doc.elements["//k"]
doc.delete_element 1
# File lib/rexml/element.rb, line 315
def delete_element element
  @elements.delete element
end
delete_namespace(namespace="xmlns") click to toggle source

Removes a namespace from this node. This only works if the namespace is actually declared in this node. If no argument is passed, deletes the default namespace.

Evaluates to: this element

doc = Document.new "<a xmlns:foo='bar' xmlns='twiddle'/>"
doc.root.delete_namespace
puts doc     # -> <a xmlns:foo='bar'/>
doc.root.delete_namespace 'foo'
puts doc     # -> <a/>
# File lib/rexml/element.rb, line 270
def delete_namespace namespace="xmlns"
  namespace = "xmlns:#{namespace}" unless namespace == 'xmlns'
  attribute = attributes.get_attribute(namespace)
  attribute.remove unless attribute.nil?
  self
end
document() click to toggle source

Evaluates to the document to which this element belongs, or nil if this element doesn't belong to a document.

# File lib/rexml/element.rb, line 131
def document
  rt = root
  rt.parent if rt
end
each_element( xpath=nil ) { |Element| ... } click to toggle source

Synonym for #elements.each

# File lib/rexml/element.rb, line 392
def each_element( xpath=nil, &block ) # :yields: Element
  @elements.each( xpath, &block )
end
each_element_with_attribute( key, value=nil, max=0, name=nil ) { |Element| ... } click to toggle source

Iterates through the child elements, yielding for each Element that has a particular attribute set.

key

the name of the attribute to search for

value

the value of the attribute

max

(optional) causes this method to return after yielding for this number of matching children

name

(optional) if supplied, this is an XPath that filters the children to check.

doc = Document.new "<a><b @id='1'/><c @id='2'/><d @id='1'/><e/></a>"
# Yields b, c, d
doc.root.each_element_with_attribute( 'id' ) {|e| p e}
# Yields b, d
doc.root.each_element_with_attribute( 'id', '1' ) {|e| p e}
# Yields b
doc.root.each_element_with_attribute( 'id', '1', 1 ) {|e| p e}
# Yields d
doc.root.each_element_with_attribute( 'id', '1', 0, 'd' ) {|e| p e}

# File lib/rexml/element.rb, line 350
def each_element_with_attribute( key, value=nil, max=0, name=nil, &block ) # :yields: Element
  each_with_something( proc {|child|
    if value.nil?
      child.attributes[key] != nil
    else
      child.attributes[key]==value
    end
  }, max, name, &block )
end
each_element_with_text( text=nil, max=0, name=nil ) { |Element| ... } click to toggle source

Iterates through the children, yielding for each Element that has a particular text set.

text

the text to search for. If nil, or not supplied, will iterate over all Element children that contain at least one Text node.

max

(optional) causes this method to return after yielding for this number of matching children

name

(optional) if supplied, this is an XPath that filters the children to check.

doc = Document.new '<a><b>b</b><c>b</c><d>d</d><e/></a>'
# Yields b, c, d
doc.each_element_with_text {|e|p e}
# Yields b, c
doc.each_element_with_text('b'){|e|p e}
# Yields b
doc.each_element_with_text('b', 1){|e|p e}
# Yields d
doc.each_element_with_text(nil, 0, 'd'){|e|p e}

# File lib/rexml/element.rb, line 381
def each_element_with_text( text=nil, max=0, name=nil, &block ) # :yields: Element
  each_with_something( proc {|child|
    if text.nil?
      child.has_text?
    else
      child.text == text
    end
  }, max, name, &block )
end
get_elements( xpath ) click to toggle source

Synonym for Element.to_a This is a little slower than calling elements.each directly.

xpath

any XPath by which to search for elements in the tree

Returns

an array of Elements that match the supplied path

# File lib/rexml/element.rb, line 400
def get_elements( xpath )
  @elements.to_a( xpath )
end
get_text(path = nil) click to toggle source

Returns the first child Text node, if any, or nil otherwise. This method returns the actual Text node, rather than the String content.

doc = Document.new "<p>some text <b>this is bold!</b> more text</p>"
# The element 'p' has two text elements, "some text " and " more text".
doc.root.get_text.value            #-> "some text "
# File lib/rexml/element.rb, line 461
def get_text path = nil
  rv = nil
  if path
    element = @elements[ path ]
    rv = element.get_text unless element.nil?
  else
    rv = @children.find { |node| node.kind_of? Text }
  end
  return rv
end
has_attributes?() click to toggle source

Evaluates to true if this element has any attributes set, false otherwise.

# File lib/rexml/element.rb, line 578
def has_attributes?
  return !@attributes.empty?
end
has_elements?() click to toggle source

Evaluates to true if this element has at least one child Element

doc = Document.new "<a><b/><c>Text</c></a>"
doc.root.has_elements               # -> true
doc.elements["/a/b"].has_elements   # -> false
doc.elements["/a/c"].has_elements   # -> false
# File lib/rexml/element.rb, line 324
def has_elements?
  !@elements.empty?
end
has_text?() click to toggle source

Evaluates to true if this element has at least one Text child

# File lib/rexml/element.rb, line 432
def has_text?
  not text().nil?
end
ignore_whitespace_nodes() click to toggle source
# File lib/rexml/element.rb, line 161
def ignore_whitespace_nodes
  @ignore_whitespace_nodes = false
  if @context
    if @context[:ignore_whitespace_nodes]
      @ignore_whitespace_nodes =
        (@context[:ignore_whitespace_nodes] == :all or
         @context[:ignore_whitespace_nodes].include? expanded_name)
    end
  end
end
inspect() click to toggle source
# File lib/rexml/element.rb, line 76
def inspect
  rv = "<#@expanded_name"

  @attributes.each_attribute do |attr|
    rv << " "
    attr.write( rv, 0 )
  end

  if children.size > 0
    rv << "> ... </>"
  else
    rv << "/>"
  end
end
instructions() click to toggle source

Get an array of all Instruction children. IMMUTABLE

# File lib/rexml/element.rb, line 655
def instructions
  find_all { |child| child.kind_of? Instruction }.freeze
end
namespace(prefix=nil) click to toggle source

Evalutas to the URI for a prefix, or the empty string if no such namespace is declared for this element. Evaluates recursively for ancestors. Returns the default namespace, if there is one.

prefix

the prefix to search for. If not supplied, returns the default namespace if one exists

Returns

the namespace URI as a String, or nil if no such namespace exists. If the namespace is undefined, returns an empty string

doc = Document.new("<a xmlns='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>")
b = doc.elements['//b']
b.namespace           # -> '1'
b.namespace("y")      # -> '2'
# File lib/rexml/element.rb, line 222
def namespace(prefix=nil)
  if prefix.nil?
    prefix = prefix()
  end
  if prefix == ''
    prefix = "xmlns"
  else
    prefix = "xmlns:#{prefix}" unless prefix[0,5] == 'xmlns'
  end
  ns = attributes[ prefix ]
  ns = parent.namespace(prefix) if ns.nil? and parent
  ns = '' if ns.nil? and prefix == 'xmlns'
  return ns
end
namespaces() click to toggle source
# File lib/rexml/element.rb, line 202
def namespaces
  namespaces = {}
  namespaces = parent.namespaces if parent
  namespaces = namespaces.merge( attributes.namespaces )
  return namespaces
end
next_element() click to toggle source

Returns the next sibling that is an element, or nil if there is no Element sibling after this one

doc = Document.new '<a><b/>text<c/></a>'
doc.root.elements['b'].next_element          #-> <c/>
doc.root.elements['c'].next_element          #-> nil
# File lib/rexml/element.rb, line 409
def next_element
  element = next_sibling
  element = element.next_sibling until element.nil? or element.kind_of? Element
  return element
end
node_type() click to toggle source
# File lib/rexml/element.rb, line 534
def node_type
  :element
end
prefixes() click to toggle source

Evaluates to an Array containing the prefixes (names) of all defined namespaces at this context node.

doc = Document.new("<a xmlns:x='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>")
doc.elements['//b'].prefixes # -> ['x', 'y']
# File lib/rexml/element.rb, line 195
def prefixes
  prefixes = []
  prefixes = parent.prefixes if parent
  prefixes |= attributes.prefixes
  return prefixes
end
previous_element() click to toggle source

Returns the previous sibling that is an element, or nil if there is no Element sibling prior to this one

doc = Document.new '<a><b/>text<c/></a>'
doc.root.elements['c'].previous_element          #-> <b/>
doc.root.elements['b'].previous_element          #-> nil
# File lib/rexml/element.rb, line 420
def previous_element
  element = previous_sibling
  element = element.previous_sibling until element.nil? or element.kind_of? Element
  return element
end
raw() click to toggle source

Evaluates to true if raw mode is set for this element. This is the case if the context has :raw set to :all or an array containing the name of this element.

The evaluation is tested against expanded_name, and so is namespace sensitive.

# File lib/rexml/element.rb, line 178
def raw
  @raw = (@context and @context[:raw] and
          (@context[:raw] == :all or
           @context[:raw].include? expanded_name))
           @raw
end
root() click to toggle source
# File lib/rexml/element.rb, line 123
def root
  return elements[1] if self.kind_of? Document
  return self if parent.kind_of? Document or parent.nil?
  return parent.root
end
root_node() click to toggle source

Evaluates to the root node of the document that this element belongs to. If this element doesn't belong to a document, but does belong to another Element, the parent's root will be returned, until the earliest ancestor is found.

Note that this is not the same as the document element. In the following example, <a> is the document element, and the root node is the parent node of the document element. You may ask yourself why the root node is useful: consider the doctype and XML declaration, and any processing instructions before the document element… they are children of the root node, or siblings of the document element. The only time this isn't true is when an Element is created that is not part of any Document. In this case, the ancestor that has no parent acts as the root node.

d = Document.new '<a><b><c/></b></a>'
a = d[1] ; c = a[1][1]
d.root_node == d   # TRUE
a.root_node        # namely, d
c.root_node        # again, d
# File lib/rexml/element.rb, line 119
def root_node
  parent.nil? ? self : parent.root_node
end
text( path = nil ) click to toggle source

A convenience method which returns the String value of the first child text element, if one exists, and nil otherwise.

Note that an element may have multiple Text elements, perhaps separated by other children. Be aware that this method only returns the first Text node.

This method returns the value of the first text child node, which ignores the raw setting, so always returns normalized text. See the Text::value documentation.

doc = Document.new "<p>some text <b>this is bold!</b> more text</p>"
# The element 'p' has two text elements, "some text " and " more text".
doc.root.text              #-> "some text "
# File lib/rexml/element.rb, line 450
def text( path = nil )
  rv = get_text(path)
  return rv.value unless rv.nil?
  nil
end
text=( text ) click to toggle source

Sets the first Text child of this object. See text() for a discussion about Text children.

If a Text child already exists, the child is replaced by this content. This means that Text content can be deleted by calling this method with a nil argument. In this case, the next Text child becomes the first Text child. In no case is the order of any siblings disturbed.

text

If a String, a new Text child is created and added to this Element as the first Text child. If Text, the text is set as the first Child element. If nil, then any existing first Text child is removed.

Returns

this Element.

doc = Document.new '<a><b/></a>'
doc.root.text = 'Sean'      #-> '<a><b/>Sean</a>'
doc.root.text = 'Elliott'   #-> '<a><b/>Elliott</a>'
doc.root.add_element 'c'    #-> '<a><b/>Elliott<c/></a>'
doc.root.text = 'Russell'   #-> '<a><b/>Russell<c/></a>'
doc.root.text = nil         #-> '<a><b/><c/></a>'
# File lib/rexml/element.rb, line 492
def text=( text )
  if text.kind_of? String
    text = Text.new( text, whitespace(), nil, raw() )
  elsif !text.nil? and !text.kind_of? Text
    text = Text.new( text.to_s, whitespace(), nil, raw() )
  end
  old_text = get_text
  if text.nil?
    old_text.remove unless old_text.nil?
  else
    if old_text.nil?
      self << text
    else
      old_text.replace_with( text )
    end
  end
  return self
end
texts() click to toggle source

Get an array of all Text children. IMMUTABLE

# File lib/rexml/element.rb, line 661
def texts
  find_all { |child| child.kind_of? Text }.freeze
end
whitespace() click to toggle source

Evaluates to true if whitespace is respected for this element. This is the case if:

  1. Neither :respect_whitespace nor :compress_whitespace has any value

  2. The context has :respect_whitespace set to :all or an array containing the name of this element, and :compress_whitespace isn't set to :all or an array containing the name of this element.

The evaluation is tested against expanded_name, and so is namespace sensitive.

# File lib/rexml/element.rb, line 145
def whitespace
  @whitespace = nil
  if @context
    if @context[:respect_whitespace]
      @whitespace = (@context[:respect_whitespace] == :all or
                     @context[:respect_whitespace].include? expanded_name)
    end
    @whitespace = false if (@context[:compress_whitespace] and
                            (@context[:compress_whitespace] == :all or
                             @context[:compress_whitespace].include? expanded_name)
                           )
  end
  @whitespace = true unless @whitespace == false
  @whitespace
end
write(output=$stdout, indent=-1, transitive=false, ie_hack=false) click to toggle source

DEPRECATED

See REXML::Formatters

Writes out this element, and recursively, all children.

output

output an object which supports '<< string'; this is where the

document will be written.
indent

An integer. If -1, no indenting will be used; otherwise, the indentation will be this number of spaces, and children will be indented an additional amount. Defaults to -1

transitive

If transitive is true and indent is >= 0, then the output will be pretty-printed in such a way that the added whitespace does not affect the parse tree of the document

ie_hack

Internet Explorer is the worst piece of crap to have ever been written, with the possible exception of Windows itself. Since IE is unable to parse proper XML, we have to provide a hack to generate XML that IE's limited abilities can handle. This hack inserts a space before the /> on empty tags. Defaults to false

out = ''
doc.write( out )     #-> doc is written to the string 'out'
doc.write( $stdout ) #-> doc written to the console
# File lib/rexml/element.rb, line 690
def write(output=$stdout, indent=-1, transitive=false, ie_hack=false)
  Kernel.warn("#{self.class.name}.write is deprecated.  See REXML::Formatters")
  formatter = if indent > -1
      if transitive
        require "rexml/formatters/transitive"
        REXML::Formatters::Transitive.new( indent, ie_hack )
      else
        REXML::Formatters::Pretty.new( indent, ie_hack )
      end
    else
      REXML::Formatters::Default.new( ie_hack )
    end
  formatter.write( self, output )
end
xpath() click to toggle source
# File lib/rexml/element.rb, line 538
def xpath
  path_elements = []
  cur = self
  path_elements << __to_xpath_helper( self )
  while cur.parent
    cur = cur.parent
    path_elements << __to_xpath_helper( cur )
  end
  return path_elements.reverse.join( "/" )
end


class REXML::ElementDecl - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::ElementDecl

In Files

  • lib/rexml/doctype.rb

Parent

REXML::Declaration

Public Class Methods

new( src ) click to toggle source
# File lib/rexml/doctype.rb, line 222
def initialize( src )
  super
end


class REXML::Elements - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Elements

A class which provides filtering of children for Elements, and XPath search support. You are expected to only encounter this class as the element.elements object. Therefore, you are not expected to instantiate this yourself.

In Files

  • lib/rexml/element.rb

Parent

Object

Included Modules

  • Enumerable

Public Class Methods

new(parent) click to toggle source

Constructor

parent

the parent Element

# File lib/rexml/element.rb, line 743
def initialize parent
  @element = parent
end

Public Instance Methods

<<(element=nil) click to toggle source
Alias for: add
[]( index, name=nil) click to toggle source

Fetches a child element. Filters only Element children, regardless of the XPath match.

index

the search parameter. This is either an Integer, which will be used to find the index'th child Element, or an XPath, which will be used to search for the Element. Because of the nature of XPath searches, any element in the connected XML document can be fetched through any other element. The Integer index is 1-based, not 0-based. This means that the first child element is at index 1, not 0, and the +n+th element is at index n, not n-1. This is because XPath indexes element children starting from 1, not 0, and the indexes should be the same.

name

optional, and only used in the first argument is an Integer. In that case, the index'th child Element that has the supplied name will be returned. Note again that the indexes start at 1.

Returns

the first matching Element, or nil if no child matched

doc = Document.new '<a><b/><c id="1"/><c id="2"/><d/></a>'
doc.root.elements[1]       #-> <b/>
doc.root.elements['c']     #-> <c id="1"/>
doc.root.elements[2,'c']   #-> <c id="2"/>
# File lib/rexml/element.rb, line 768
def []( index, name=nil)
  if index.kind_of? Integer
    raise "index (#{index}) must be >= 1" if index < 1
    name = literalize(name) if name
    num = 0
    @element.find { |child|
      child.kind_of? Element and
      (name.nil? ? true : child.has_name?( name )) and
      (num += 1) == index
    }
  else
    return XPath::first( @element, index )
    #{ |element|
    #       return element if element.kind_of? Element
    #}
    #return nil
  end
end
[]=( index, element ) click to toggle source

Sets an element, replacing any previous matching element. If no existing element is found ,the element is added.

index

Used to find a matching element to replace. See []().

element

The element to replace the existing element with the previous element

Returns

nil if no previous element was found.

doc = Document.new '<a/>'
doc.root.elements[10] = Element.new('b')    #-> <a><b/></a>
doc.root.elements[1]                        #-> <b/>
doc.root.elements[1] = Element.new('c')     #-> <a><c/></a>
doc.root.elements['c'] = Element.new('d')   #-> <a><d/></a>
# File lib/rexml/element.rb, line 800
def []=( index, element )
  previous = self[index]
  if previous.nil?
    @element.add element
  else
    previous.replace_with element
  end
  return previous
end
add(element=nil) click to toggle source

Adds an element

element

if supplied, is either an Element, String, or Source (see Element.initialize). If not supplied or nil, a new, default Element will be constructed

Returns

the added Element

a = Element.new('a')
a.elements.add(Element.new('b'))  #-> <a><b/></a>
a.elements.add('c')               #-> <a><b/><c/></a>
# File lib/rexml/element.rb, line 876
def add element=nil
  if element.nil?
    Element.new("", self, @element.context)
  elsif not element.kind_of?(Element)
    Element.new(element, self, @element.context)
  else
    @element << element
    element.context = @element.context
    element
  end
end
Also aliased as: <<
collect( xpath=nil ) { |e| ... } click to toggle source
# File lib/rexml/element.rb, line 908
def collect( xpath=nil )
  collection = []
  XPath::each( @element, xpath ) {|e|
    collection << yield(e)  if e.kind_of?(Element)
  }
  collection
end
delete(element) click to toggle source

Deletes a child Element

element

Either an Element, which is removed directly; an xpath, where the first matching child is removed; or an Integer, where the n'th Element is removed.

Returns

the removed child

doc = Document.new '<a><b/><c/><c id="1"/></a>'
b = doc.root.elements[1]
doc.root.elements.delete b           #-> <a><c/><c id="1"/></a>
doc.elements.delete("a/c[@id='1']")  #-> <a><c/></a>
doc.root.elements.delete 1           #-> <a/>
# File lib/rexml/element.rb, line 840
def delete element
  if element.kind_of? Element
    @element.delete element
  else
    el = self[element]
    el.remove if el
  end
end
delete_all( xpath ) click to toggle source

Removes multiple elements. Filters for Element children, regardless of XPath matching.

xpath

all elements matching this String path are removed.

Returns

an Array of Elements that have been removed

doc = Document.new '<a><c/><c/><c/><c/></a>'
deleted = doc.elements.delete_all 'a/c' #-> [<c/>, <c/>, <c/>, <c/>]
# File lib/rexml/element.rb, line 855
def delete_all( xpath )
  rv = []
  XPath::each( @element, xpath) {|element|
    rv << element if element.kind_of? Element
  }
  rv.each do |element|
    @element.delete element
    element.remove
  end
  return rv
end
each( xpath=nil ) { |e| ... } click to toggle source

Iterates through all of the child Elements, optionally filtering them by a given XPath

xpath

optional. If supplied, this is a String XPath, and is used to filter the children, so that only matching children are yielded. Note that XPaths are automatically filtered for Elements, so that non-Element children will not be yielded

doc = Document.new '<a><b/><c/><d/>sean<b/><c/><d/></a>'
doc.root.elements.each {|e|p e}       #-> Yields b, c, d, b, c, d elements
doc.root.elements.each('b') {|e|p e}  #-> Yields b, b elements
doc.root.elements.each('child::node()')  {|e|p e}
#-> Yields <b/>, <c/>, <d/>, <b/>, <c/>, <d/>
XPath.each(doc.root, 'child::node()', &block)
#-> Yields <b/>, <c/>, <d/>, sean, <b/>, <c/>, <d/>

# File lib/rexml/element.rb, line 904
def each( xpath=nil )
  XPath::each( @element, xpath ) {|e| yield e if e.kind_of? Element }
end
empty?() click to toggle source

Returns true if there are no Element children, false otherwise

# File lib/rexml/element.rb, line 811
def empty?
  @element.find{ |child| child.kind_of? Element}.nil?
end
index(element) click to toggle source

Returns the index of the supplied child (starting at 1), or -1 if the element is not a child

element

an Element child

# File lib/rexml/element.rb, line 818
def index element
  rv = 0
  found = @element.find do |child|
    child.kind_of? Element and
    (rv += 1) and
    child == element
  end
  return rv if found == element
  return -1
end
inject( xpath=nil, initial=nil ) { |initial, e| ... } click to toggle source
# File lib/rexml/element.rb, line 916
def inject( xpath=nil, initial=nil )
  first = true
  XPath::each( @element, xpath ) {|e|
    if (e.kind_of? Element)
      if (first and initial == nil)
        initial = e
        first = false
      else
        initial = yield( initial, e ) if e.kind_of? Element
      end
    end
  }
  initial
end
size() click to toggle source

Returns the number of Element children of the parent object.

doc = Document.new '<a>sean<b/>elliott<b/>russell<b/></a>'
doc.root.size            #-> 6, 3 element and 3 text nodes
doc.root.elements.size   #-> 3
# File lib/rexml/element.rb, line 935
def size
  count = 0
  @element.each {|child| count+=1 if child.kind_of? Element }
  count
end
to_a( xpath=nil ) click to toggle source

Returns an Array of Element children. An XPath may be supplied to filter the children. Only Element children are returned, even if the supplied XPath matches non-Element children.

doc = Document.new '<a>sean<b/>elliott<c/></a>'
doc.root.elements.to_a                  #-> [ <b/>, <c/> ]
doc.root.elements.to_a("child::node()") #-> [ <b/>, <c/> ]
XPath.match(doc.root, "child::node()")  #-> [ sean, <b/>, elliott, <c/> ]
# File lib/rexml/element.rb, line 948
def to_a( xpath=nil )
  rv = XPath.match( @element, xpath )
  return rv.find_all{|e| e.kind_of? Element} if xpath
  rv
end


module REXML::Encoding - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::Encoding

In Files

  • lib/rexml/encoding.rb

Attributes

encoding[R]

ID —> Encoding name

Public Instance Methods

decode(string) click to toggle source
# File lib/rexml/encoding.rb, line 27
def decode(string)
  string.encode(::Encoding::UTF_8, @encoding)
end
encode(string) click to toggle source
# File lib/rexml/encoding.rb, line 23
def encode(string)
  string.encode(@encoding)
end
encoding=(encoding) click to toggle source
# File lib/rexml/encoding.rb, line 5
def encoding=(encoding)
  encoding = encoding.name if encoding.is_a?(Encoding)
  if encoding.is_a?(String)
    original_encoding = encoding
    encoding = find_encoding(encoding)
    unless encoding
      raise ArgumentError, "Bad encoding name #{original_encoding}"
    end
  end
  return false if defined?(@encoding) and encoding == @encoding
  if encoding
    @encoding = encoding.upcase
  else
    @encoding = 'UTF-8'
  end
  true
end


class REXML::Entity - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Entity

God, I hate DTDs. I really do. Why this idiot standard still plagues us is beyond me.

In Files

  • lib/rexml/entity.rb

Parent

REXML::Child

Included Modules

  • REXML::XMLTokens

Constants

ENTITYDECL
ENTITYDEF
ENTITYVALUE
EXTERNALID
GEDECL
NDATADECL
PEDECL
PEDEF
PEREFERENCE
PEREFERENCE_RE
PUBIDCHAR
PUBIDLITERAL
SYSTEMLITERAL

Attributes

external[R]
name[R]
ndata[R]
pubid[R]
ref[R]

Public Class Methods

matches?(string) click to toggle source

Evaluates whether the given string matchs an entity definition, returning true if so, and false otherwise.

# File lib/rexml/entity.rb, line 68
def Entity::matches? string
  (ENTITYDECL =~ string) == 0
end
new(stream, value=nil, parent=nil, reference=false) click to toggle source

Create a new entity. Simple entities can be constructed by passing a name, value to the constructor; this creates a generic, plain entity reference. For anything more complicated, you have to pass a Source to the constructor with the entity definition, or use the accessor methods. WARNING: There is no validation of entity state except when the entity is read from a stream. If you start poking around with the accessors, you can easily create a non-conformant Entity. The best thing to do is dump the stupid DTDs and use XMLSchema instead.

e = Entity.new( 'amp', '&' )
# File lib/rexml/entity.rb, line 35
def initialize stream, value=nil, parent=nil, reference=false
  super(parent)
  @ndata = @pubid = @value = @external = nil
  if stream.kind_of? Array
    @name = stream[1]
    if stream[-1] == '%'
      @reference = true
      stream.pop
    else
      @reference = false
    end
    if stream[2] =~ /SYSTEM|PUBLIC/
      @external = stream[2]
      if @external == 'SYSTEM'
        @ref = stream[3]
        @ndata = stream[4] if stream.size == 5
      else
        @pubid = stream[3]
        @ref = stream[4]
      end
    else
      @value = stream[2]
    end
  else
    @reference = reference
    @external = nil
    @name = stream
    @value = value
  end
end

Public Instance Methods

normalized() click to toggle source

Returns the value of this entity unprocessed – raw. This is the normalized value; that is, with all %ent; and &ent; entities intact

# File lib/rexml/entity.rb, line 87
def normalized
  @value
end
to_s() click to toggle source

Returns this entity as a string. See write().

# File lib/rexml/entity.rb, line 121
def to_s
  rv = ''
  write rv
  rv
end
unnormalized() click to toggle source

Evaluates to the unnormalized value of this entity; that is, replacing all entities – both %ent; and &ent; entities. This differs from +value()+ in that value only replaces %ent; entities.

# File lib/rexml/entity.rb, line 75
def unnormalized
  document.record_entity_expansion unless document.nil?
  v = value()
  return nil if v.nil?
  @unnormalized = Text::unnormalize(v, parent)
  @unnormalized
end
value() click to toggle source

Returns the value of this entity. At the moment, only internal entities are processed. If the value contains internal references (IE, %blah;), those are replaced with their values. IE, if the doctype contains:

<!ENTITY % foo "bar">
<!ENTITY yada "nanoo %foo; nanoo>

then:

doctype.entity('yada').value   #-> "nanoo bar nanoo"
# File lib/rexml/entity.rb, line 136
def value
  if @value
    matches = @value.scan(PEREFERENCE_RE)
    rv = @value.clone
    if @parent
      matches.each do |entity_reference|
        entity_value = @parent.entity( entity_reference[0] )
        rv.gsub!( /%#{entity_reference.join};/m, entity_value )
      end
    end
    return rv
  end
  nil
end
write(out, indent=-1) click to toggle source

Write out a fully formed, correct entity definition (assuming the Entity object itself is valid.)

out

An object implementing <TT>&lt;&lt;<TT> to which the entity will be output

indent

DEPRECATED and ignored

# File lib/rexml/entity.rb, line 99
def write out, indent=-1
  out << '<!ENTITY '
  out << '% ' if @reference
  out << @name
  out << ' '
  if @external
    out << @external << ' '
    if @pubid
      q = @pubid.include?('"')?"'":'"'
      out << q << @pubid << q << ' '
    end
    q = @ref.include?('"')?"'":'"'
    out << q << @ref << q
    out << ' NDATA ' << @ndata if @ndata
  else
    q = @value.include?('"')?"'":'"'
    out << q << @value << q
  end
  out << '>'
end


module REXML::EntityConst - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::EntityConst

This is a set of entity constants – the ones defined in the XML specification. These are gt, lt, amp, quot and apos.

In Files

  • lib/rexml/entity.rb

Constants

AMP

+&+

APOS

+'+

GT

+>+

LT

+<+

QUOT

+“+


class REXML::ExternalEntity - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::ExternalEntity

In Files

  • lib/rexml/doctype.rb

Parent

REXML::Child

Public Class Methods

new( src ) click to toggle source
# File lib/rexml/doctype.rb, line 228
def initialize( src )
  super()
  @entity = src
end

Public Instance Methods

to_s() click to toggle source
# File lib/rexml/doctype.rb, line 232
def to_s
  @entity
end
write( output, indent ) click to toggle source
# File lib/rexml/doctype.rb, line 235
def write( output, indent )
  output << @entity
end


module REXML::Formatters - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::Formatters

In Files

  • lib/rexml/formatters/default.rb
  • lib/rexml/formatters/pretty.rb
  • lib/rexml/formatters/transitive.rb


class REXML::Formatters::Default - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Formatters::Default

In Files

  • lib/rexml/formatters/default.rb

Parent

Object

Public Class Methods

new( ie_hack=false ) click to toggle source

Prints out the XML document with no formatting – except if id_hack is set.

ie_hack

If set to true, then inserts whitespace before the close of an empty tag, so that IE's bad XML parser doesn't choke.

# File lib/rexml/formatters/default.rb, line 10
def initialize( ie_hack=false )
  @ie_hack = ie_hack
end

Public Instance Methods

write( node, output ) click to toggle source

Writes the node to some output.

node

The node to write

output

A class implementing &lt;&lt;. Pass in an Output object to change the output encoding.

# File lib/rexml/formatters/default.rb, line 21
def write( node, output )
  case node

  when Document
    if node.xml_decl.encoding != 'UTF-8' && !output.kind_of?(Output)
      output = Output.new( output, node.xml_decl.encoding )
    end
    write_document( node, output )

  when Element
    write_element( node, output )

  when Declaration, ElementDecl, NotationDecl, ExternalEntity, Entity,
       Attribute, AttlistDecl
    node.write( output,-1 )

  when Instruction
    write_instruction( node, output )

  when DocType, XMLDecl
    node.write( output )

  when Comment
    write_comment( node, output )

  when CData
    write_cdata( node, output )

  when Text
    write_text( node, output )

  else
    raise Exception.new("XML FORMATTING ERROR")

  end
end

Protected Instance Methods

write_cdata( node, output ) click to toggle source
# File lib/rexml/formatters/default.rb, line 96
def write_cdata( node, output )
  output << CData::START
  output << node.to_s
  output << CData::STOP
end
write_comment( node, output ) click to toggle source
# File lib/rexml/formatters/default.rb, line 90
def write_comment( node, output )
  output << Comment::START
  output << node.to_s
  output << Comment::STOP
end
write_document( node, output ) click to toggle source
# File lib/rexml/formatters/default.rb, line 59
def write_document( node, output )
  node.children.each { |child| write( child, output ) }
end
write_element( node, output ) click to toggle source
# File lib/rexml/formatters/default.rb, line 63
def write_element( node, output )
  output << "<#{node.expanded_name}"

  node.attributes.to_a.map { |a|
    Hash === a ? a.values : a
  }.flatten.sort_by {|attr| attr.name}.each do |attr|
    output << " "
    attr.write( output )
  end unless node.attributes.empty?

  if node.children.empty?
    output << " " if @ie_hack
    output << "/"
  else
    output << ">"
    node.children.each { |child|
      write( child, output )
    }
    output << "</#{node.expanded_name}"
  end
  output << ">"
end
write_instruction( node, output ) click to toggle source
# File lib/rexml/formatters/default.rb, line 102
def write_instruction( node, output )
  output << Instruction::START.sub(/\/, '')
  output << node.target
  output << ' '
  output << node.content
  output << Instruction::STOP.sub(/\/, '')
end
write_text( node, output ) click to toggle source
# File lib/rexml/formatters/default.rb, line 86
def write_text( node, output )
  output << node.to_s()
end


class REXML::Formatters::Pretty - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Formatters::Pretty

Pretty-prints an XML document. This destroys whitespace in text nodes and will insert carriage returns and indentations.

TODO: Add an option to print attributes on new lines

In Files

  • lib/rexml/formatters/pretty.rb

Parent

REXML::Formatters::Default

Attributes

compact[RW]

If compact is set to true, then the formatter will attempt to use as little space as possible

width[RW]

The width of a page. Used for formatting text

Public Class Methods

new( indentation=2, ie_hack=false ) click to toggle source

Create a new pretty printer.

output

An object implementing '<<(String)', to which the output will be written.

indentation

An integer greater than 0. The indentation of each level will be this number of spaces. If this is < 1, the behavior of this object is undefined. Defaults to 2.

ie_hack

If true, the printer will insert whitespace before closing empty tags, thereby allowing Internet Explorer's feeble XML parser to function. Defaults to false.

# File lib/rexml/formatters/pretty.rb, line 29
def initialize( indentation=2, ie_hack=false )
  @indentation = indentation
  @level = 0
  @ie_hack = ie_hack
  @width = 80
  @compact = false
end

Protected Instance Methods

write_cdata( node, output) click to toggle source
# File lib/rexml/formatters/pretty.rb, line 101
def write_cdata( node, output)
  output << ' ' * @level
  super
end
write_comment( node, output) click to toggle source
# File lib/rexml/formatters/pretty.rb, line 96
def write_comment( node, output)
  output << ' ' * @level
  super
end
write_document( node, output ) click to toggle source
# File lib/rexml/formatters/pretty.rb, line 106
def write_document( node, output )
  # Ok, this is a bit odd.  All XML documents have an XML declaration,
  # but it may not write itself if the user didn't specifically add it,
  # either through the API or in the input document.  If it doesn't write
  # itself, then we don't need a carriage return... which makes this
  # logic more complex.
  node.children.each { |child|
    next if child == node.children[-1] and child.instance_of?(Text)
    unless child == node.children[0] or child.instance_of?(Text) or
      (child == node.children[1] and !node.children[0].writethis)
      output << "\n"
    end
    write( child, output )
  }
end
write_element(node, output) click to toggle source
# File lib/rexml/formatters/pretty.rb, line 38
def write_element(node, output)
  output << ' '*@level
  output << "<#{node.expanded_name}"

  node.attributes.each_attribute do |attr|
    output << " "
    attr.write( output )
  end unless node.attributes.empty?

  if node.children.empty?
    if @ie_hack
      output << " "
    end
    output << "/"
  else
    output << ">"
    # If compact and all children are text, and if the formatted output
    # is less than the specified width, then try to print everything on
    # one line
    skip = false
    if compact
      if node.children.inject(true) {|s,c| s & c.kind_of?(Text)}
        string = ""
        old_level = @level
        @level = 0
        node.children.each { |child| write( child, string ) }
        @level = old_level
        if string.length < @width
          output << string
          skip = true
        end
      end
    end
    unless skip
      output << "\n"
      @level += @indentation
      node.children.each { |child|
        next if child.kind_of?(Text) and child.to_s.strip.length == 0
        write( child, output )
        output << "\n"
      }
      @level -= @indentation
      output << ' '*@level
    end
    output << "</#{node.expanded_name}"
  end
  output << ">"
end
write_text( node, output ) click to toggle source
# File lib/rexml/formatters/pretty.rb, line 87
def write_text( node, output )
  s = node.to_s()
  s.gsub!(/\s/,' ')
  s.squeeze!(" ")
  s = wrap(s, @width - @level)
  s = indent_text(s, @level, " ", true)
  output << (' '*@level + s)
end


class REXML::Formatters::Transitive - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Formatters::Transitive

The Transitive formatter writes an XML document that parses to an identical document as the source document. This means that no extra whitespace nodes are inserted, and whitespace within text nodes is preserved. Within these constraints, the document is pretty-printed, with whitespace inserted into the metadata to introduce formatting.

Note that this is only useful if the original XML is not already formatted. Since this formatter does not alter whitespace nodes, the results of formatting already formatted XML will be odd.

In Files

  • lib/rexml/formatters/transitive.rb

Parent

REXML::Formatters::Default

Public Class Methods

new( indentation=2, ie_hack=false ) click to toggle source
# File lib/rexml/formatters/transitive.rb, line 15
def initialize( indentation=2, ie_hack=false )
  @indentation = indentation
  @level = 0
  @ie_hack = ie_hack
end

Protected Instance Methods

write_element( node, output ) click to toggle source
# File lib/rexml/formatters/transitive.rb, line 22
def write_element( node, output )
  output << "<#{node.expanded_name}"

  node.attributes.each_attribute do |attr|
    output << " "
    attr.write( output )
  end unless node.attributes.empty?

  output << "\n"
  output << ' '*@level
  if node.children.empty?
    output << " " if @ie_hack
    output << "/"
  else
    output << ">"
    # If compact and all children are text, and if the formatted output
    # is less than the specified width, then try to print everything on
    # one line
    @level += @indentation
    node.children.each { |child|
      write( child, output )
    }
    @level -= @indentation
    output << "</#{node.expanded_name}"
    output << "\n"
    output << ' '*@level
  end
  output << ">"
end
write_text( node, output ) click to toggle source
# File lib/rexml/formatters/transitive.rb, line 52
def write_text( node, output )
  output << node.to_s()
end


module REXML::Functions - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::Functions

If you add a method, keep in mind two things: (1) the first argument will always be a list of nodes from which to filter. In the case of context methods (such as position), the function should return an array with a value for each child in the array. (2) all method calls from XML will have “-” replaced with “_”. Therefore, in XML, “local-name()” is identical (and actually becomes) “::local_name()”

In Files

  • lib/rexml/functions.rb

Public Class Methods

boolean( object=nil ) click to toggle source

UNTESTED

# File lib/rexml/functions.rb, line 277
def Functions::boolean( object=nil )
  if object.kind_of? String
    if object =~ /\d+/
      return object.to_f != 0
    else
      return object.size > 0
    end
  elsif object.kind_of? Array
    object = object.find{|x| x and true}
  end
  return object ? true : false
end
ceiling( number ) click to toggle source
# File lib/rexml/functions.rb, line 373
def Functions::ceiling( number )
  number(number).ceil
end
compare_language(lang1, lang2) click to toggle source
# File lib/rexml/functions.rb, line 324
def Functions::compare_language lang1, lang2
  lang2.downcase.index(lang1.downcase) == 0
end
concat( *objects ) click to toggle source

UNTESTED

# File lib/rexml/functions.rb, line 152
def Functions::concat( *objects )
  objects.join
end
contains( string, test ) click to toggle source

Fixed by Mike Stok

# File lib/rexml/functions.rb, line 162
def Functions::contains( string, test )
  string(string).include?(string(test))
end
context=(value) click to toggle source
# File lib/rexml/functions.rb, line 19
def Functions::context=(value); @@context = value; end
count( node_set ) click to toggle source

Returns the size of the given list of nodes.

# File lib/rexml/functions.rb, line 41
def Functions::count( node_set )
  node_set.size
end
false( ) click to toggle source

UNTESTED

# File lib/rexml/functions.rb, line 301
def Functions::false(  )
  false
end
floor( number ) click to toggle source
# File lib/rexml/functions.rb, line 369
def Functions::floor( number )
  number(number).floor
end
get_namespace( node_set = nil ) { |context| ... } click to toggle source

Helper method.

# File lib/rexml/functions.rb, line 68
def Functions::get_namespace( node_set = nil )
  if node_set == nil
    yield @@context[:node] if defined? @@context[:node].namespace
  else
    if node_set.respond_to? :each
      node_set.each { |node| yield node if defined? node.namespace }
    elsif node_set.respond_to? :namespace
      yield node_set
    end
  end
end
id( object ) click to toggle source

Since REXML is non-validating, this method is not implemented as it requires a DTD

# File lib/rexml/functions.rb, line 47
def Functions::id( object )
end
lang( language ) click to toggle source

UNTESTED

# File lib/rexml/functions.rb, line 306
def Functions::lang( language )
  lang = false
  node = @@context[:node]
  attr = nil
  until node.nil?
    if node.node_type == :element
      attr = node.attributes["xml:lang"]
      unless attr.nil?
        lang = compare_language(string(language), attr)
        break
      else
      end
    end
    node = node.parent
  end
  lang
end
last( ) click to toggle source

Returns the last node of the given list of nodes.

# File lib/rexml/functions.rb, line 32
def Functions::last( )
  @@context[:size]
end
local_name( node_set=nil ) click to toggle source

UNTESTED

# File lib/rexml/functions.rb, line 51
def Functions::local_name( node_set=nil )
  get_namespace( node_set ) do |node|
    return node.local_name
  end
end
method_missing( id ) click to toggle source
# File lib/rexml/functions.rb, line 389
def Functions::method_missing( id )
  puts "METHOD MISSING #{id.id2name}"
  XPath.match( @@context[:node], id.id2name )
end
name( node_set=nil ) click to toggle source
# File lib/rexml/functions.rb, line 61
def Functions::name( node_set=nil )
  get_namespace( node_set ) do |node|
    node.expanded_name
  end
end
namespace_context() click to toggle source
# File lib/rexml/functions.rb, line 16
def Functions::namespace_context ; @@namespace_context ; end
namespace_context=(x) click to toggle source
# File lib/rexml/functions.rb, line 14
def Functions::namespace_context=(x) ; @@namespace_context=x ; end
namespace_uri( node_set=nil ) click to toggle source
# File lib/rexml/functions.rb, line 57
def Functions::namespace_uri( node_set=nil )
  get_namespace( node_set ) {|node| node.namespace}
end
normalize_space( string=nil ) click to toggle source

UNTESTED

# File lib/rexml/functions.rb, line 224
def Functions::normalize_space( string=nil )
  string = string(@@context[:node]) if string.nil?
  if string.kind_of? Array
    string.collect{|x| string.to_s.strip.gsub(/\s+/m, ' ') if string}
  else
    string.to_s.strip.gsub(/\s+/m, ' ')
  end
end
not( object ) click to toggle source

UNTESTED

# File lib/rexml/functions.rb, line 291
def Functions::not( object )
  not boolean( object )
end
number( object=nil ) click to toggle source

a string that consists of optional whitespace followed by an optional minus sign followed by a Number followed by whitespace is converted to the IEEE 754 number that is nearest (according to the IEEE 754 round-to-nearest rule) to the mathematical value represented by the string; any other string is converted to NaN

boolean true is converted to 1; boolean false is converted to 0

a node-set is first converted to a string as if by a call to the string function and then converted in the same way as a string argument

an object of a type other than the four basic types is converted to a number in a way that is dependent on that type

# File lib/rexml/functions.rb, line 341
def Functions::number( object=nil )
  object = @@context[:node] unless object
  case object
  when true
    Float(1)
  when false
    Float(0)
  when Array
    number(string( object ))
  when Numeric
    object.to_f
  else
    str = string( object )
    # If XPath ever gets scientific notation...
    #if str =~ /^\s*-?(\d*\.?\d+|\d+\.)([Ee]\d*)?\s*$/
    if str =~ /^\s*-?(\d*\.?\d+|\d+\.)\s*$/
      str.to_f
    else
      (0.0 / 0.0)
    end
  end
end
position( ) click to toggle source
# File lib/rexml/functions.rb, line 36
def Functions::position( )
  @@context[:index]
end
processing_instruction( node ) click to toggle source
# File lib/rexml/functions.rb, line 385
def Functions::processing_instruction( node )
  node.node_type == :processing_instruction
end
round( number ) click to toggle source
# File lib/rexml/functions.rb, line 377
def Functions::round( number )
  begin
    number(number).round
  rescue FloatDomainError
    number(number)
  end
end
starts_with( string, test ) click to toggle source

Fixed by Mike Stok

# File lib/rexml/functions.rb, line 157
def Functions::starts_with( string, test )
  string(string).index(string(test)) == 0
end
string( object=nil ) click to toggle source

A node-set is converted to a string by returning the string-value of the node in the node-set that is first in document order. If the node-set is empty, an empty string is returned.

A number is converted to a string as follows

NaN is converted to the string NaN

positive zero is converted to the string 0

negative zero is converted to the string 0

positive infinity is converted to the string Infinity

negative infinity is converted to the string -Infinity

if the number is an integer, the number is represented in decimal form as a Number with no decimal point and no leading zeros, preceded by a minus sign (-) if the number is negative

otherwise, the number is represented in decimal form as a Number including a decimal point with at least one digit before the decimal point and at least one digit after the decimal point, preceded by a minus sign (-) if the number is negative; there must be no leading zeros before the decimal point apart possibly from the one required digit immediately before the decimal point; beyond the one required digit after the decimal point there must be as many, but only as many, more digits as are needed to uniquely distinguish the number from all other IEEE 754 numeric values.

The boolean false value is converted to the string false. The boolean true value is converted to the string true.

An object of a type other than the four basic types is converted to a string in a way that is dependent on that type.

# File lib/rexml/functions.rb, line 115
def Functions::string( object=nil )
  #object = @context unless object
  if object.instance_of? Array
    string( object[0] )
  elsif defined? object.node_type
    if object.node_type == :attribute
      object.value
    elsif object.node_type == :element || object.node_type == :document
      string_value(object)
    else
      object.to_s
    end
  elsif object.nil?
    return ""
  else
    object.to_s
  end
end
string_length( string ) click to toggle source

UNTESTED

# File lib/rexml/functions.rb, line 219
def Functions::string_length( string )
  string(string).length
end
string_value( o ) click to toggle source

A node-set is converted to a string by returning the concatenation of the string-value of each of the children of the node in the node-set that is first in document order. If the node-set is empty, an empty string is returned.

# File lib/rexml/functions.rb, line 139
def Functions::string_value( o )
  rv = ""
  o.children.each { |e|
    if e.node_type == :text
      rv << e.to_s
    elsif e.node_type == :element
      rv << string_value( e )
    end
  }
  rv
end
substring( string, start, length=nil ) click to toggle source

Take equal portions of Mike Stok and Sean Russell; mix vigorously, and pour into a tall, chilled glass. Serves 10,000.

# File lib/rexml/functions.rb, line 186
def Functions::substring( string, start, length=nil )
  ruby_string = string(string)
  ruby_length = if length.nil?
                  ruby_string.length.to_f
                else
                  number(length)
                end
  ruby_start = number(start)

  # Handle the special cases
  return '' if (
    ruby_length.nan? or
    ruby_start.nan? or
    ruby_start.infinite?
  )

  infinite_length = ruby_length.infinite? == 1
  ruby_length = ruby_string.length if infinite_length

  # Now, get the bounds.  The XPath bounds are 1..length; the ruby bounds
  # are 0..length.  Therefore, we have to offset the bounds by one.
  ruby_start = ruby_start.round - 1
  ruby_length = ruby_length.round

  if ruby_start < 0
   ruby_length += ruby_start unless infinite_length
   ruby_start = 0
  end
  return '' if ruby_length <= 0
  ruby_string[ruby_start,ruby_length]
end
substring_after( string, test ) click to toggle source

Kouhei fixed this too

# File lib/rexml/functions.rb, line 178
def Functions::substring_after( string, test )
  ruby_string = string(string)
  return $1 if ruby_string =~ /#{test}(.*)/
  ""
end
substring_before( string, test ) click to toggle source

Kouhei fixed this

# File lib/rexml/functions.rb, line 167
def Functions::substring_before( string, test )
  ruby_string = string(string)
  ruby_index = ruby_string.index(string(test))
  if ruby_index.nil?
    ""
  else
    ruby_string[ 0...ruby_index ]
  end
end
sum( nodes ) click to toggle source
# File lib/rexml/functions.rb, line 364
def Functions::sum( nodes )
  nodes = [nodes] unless nodes.kind_of? Array
  nodes.inject(0) { |r,n| r += number(string(n)) }
end
text( ) click to toggle source
# File lib/rexml/functions.rb, line 21
def Functions::text( )
  if @@context[:node].node_type == :element
    return @@context[:node].find_all{|n| n.node_type == :text}.collect{|n| n.value}
  elsif @@context[:node].node_type == :text
    return @@context[:node].value
  else
    return false
  end
end
translate( string, tr1, tr2 ) click to toggle source

This is entirely Mike Stok's beast

# File lib/rexml/functions.rb, line 234
def Functions::translate( string, tr1, tr2 )
  from = string(tr1)
  to = string(tr2)

  # the map is our translation table.
  #
  # if a character occurs more than once in the
  # from string then we ignore the second &
  # subsequent mappings
  #
  # if a character maps to nil then we delete it
  # in the output.  This happens if the from
  # string is longer than the to string
  #
  # there's nothing about - or ^ being special in
  # http://www.w3.org/TR/xpath#function-translate
  # so we don't build ranges or negated classes

  map = Hash.new
  0.upto(from.length - 1) { |pos|
    from_char = from[pos]
    unless map.has_key? from_char
      map[from_char] =
      if pos < to.length
        to[pos]
      else
        nil
      end
    end
  }

  if ''.respond_to? :chars
    string(string).chars.collect { |c|
      if map.has_key? c then map[c] else c end
    }.compact.join
  else
    string(string).unpack('U*').collect { |c|
      if map.has_key? c then map[c] else c end
    }.compact.pack('U*')
  end
end
true( ) click to toggle source

UNTESTED

# File lib/rexml/functions.rb, line 296
def Functions::true( )
  true
end
variables() click to toggle source
# File lib/rexml/functions.rb, line 17
def Functions::variables ; @@variables ; end
variables=(x) click to toggle source
# File lib/rexml/functions.rb, line 15
def Functions::variables=(x) ; @@variables=x ; end


class REXML::IOSource - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::IOSource

A Source that wraps an IO. See the Source class for method documentation

In Files

  • lib/rexml/source.rb

Parent

REXML::Source

Public Class Methods

new(arg, block_size=500, encoding=nil) click to toggle source

block_size has been deprecated

# File lib/rexml/source.rb, line 161
def initialize(arg, block_size=500, encoding=nil)
  @er_source = @source = arg
  @to_utf = false
  @pending_buffer = nil

  if encoding
    super("", encoding)
  else
    super(@source.read(3) || "")
  end

  if !@to_utf and
      @buffer.respond_to?(:force_encoding) and
      @source.respond_to?(:external_encoding) and
      @source.external_encoding != ::Encoding::UTF_8
    @force_utf8 = true
  else
    @force_utf8 = false
  end
end

Public Instance Methods

consume( pattern ) click to toggle source
# File lib/rexml/source.rb, line 213
def consume( pattern )
  match( pattern, true )
end
current_line() click to toggle source

@return the current line in the source

# File lib/rexml/source.rb, line 242
def current_line
  begin
    pos = @er_source.pos        # The byte position in the source
    lineno = @er_source.lineno  # The XML < position in the source
    @er_source.rewind
    line = 0                    # The \r\n position in the source
    begin
      while @er_source.pos < pos
        @er_source.readline
        line += 1
      end
    rescue
    end
  rescue IOError
    pos = -1
    line = -1
  end
  [pos, lineno, line]
end
empty?() click to toggle source
# File lib/rexml/source.rb, line 233
def empty?
  super and ( @source.nil? || @source.eof? )
end
match( pattern, cons=false ) click to toggle source
# File lib/rexml/source.rb, line 217
def match( pattern, cons=false )
  rv = pattern.match(@buffer)
  @buffer = $' if cons and rv
  while !rv and @source
    begin
      @buffer << readline
      rv = pattern.match(@buffer)
      @buffer = $' if cons and rv
    rescue
      @source = nil
    end
  end
  rv.taint
  rv
end
position() click to toggle source
# File lib/rexml/source.rb, line 237
def position
  @er_source.pos rescue 0
end
read() click to toggle source
# File lib/rexml/source.rb, line 205
def read
  begin
    @buffer << readline
  rescue Exception, NameError
    @source = nil
  end
end
scan(pattern, cons=false) click to toggle source
# File lib/rexml/source.rb, line 182
def scan(pattern, cons=false)
  rv = super
  # You'll notice that this next section is very similar to the same
  # section in match(), but just a liiittle different.  This is
  # because it is a touch faster to do it this way with scan()
  # than the way match() does it; enough faster to warrent duplicating
  # some code
  if rv.size == 0
    until @buffer =~ pattern or @source.nil?
      begin
        @buffer << readline
      rescue Iconv::IllegalSequence
        raise
      rescue
        @source = nil
      end
    end
    rv = super
  end
  rv.taint
  rv
end


class REXML::Instruction - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Instruction

Represents an XML Instruction; IE, <? … ?> TODO: Add parent arg (3rd arg) to constructor

In Files

  • lib/rexml/instruction.rb

Parent

REXML::Child

Constants

START
STOP

Attributes

content[RW]

target is the “name” of the Instruction; IE, the “tag” in <?tag …?> content is everything else.

target[RW]

target is the “name” of the Instruction; IE, the “tag” in <?tag …?> content is everything else.

Public Class Methods

new(target, content=nil) click to toggle source

Constructs a new Instruction @param target can be one of a number of things. If String, then the target of this instruction is set to this. If an Instruction, then the Instruction is shallowly cloned (target and content are copied). If a Source, then the source is scanned and parsed for an Instruction declaration. @param content Must be either a String, or a Parent. Can only be a Parent if the target argument is a Source. Otherwise, this String is set as the content of this instruction.

# File lib/rexml/instruction.rb, line 24
def initialize(target, content=nil)
  if target.kind_of? String
    super()
    @target = target
    @content = content
  elsif target.kind_of? Instruction
    super(content)
    @target = target.target
    @content = target.content
  end
  @content.strip! if @content
end

Public Instance Methods

==( other ) click to toggle source

@return true if other is an Instruction, and the content and target of the other matches the target and content of this object.

# File lib/rexml/instruction.rb, line 56
def ==( other )
  other.kind_of? Instruction and
  other.target == @target and
  other.content == @content
end
clone() click to toggle source
# File lib/rexml/instruction.rb, line 37
def clone
  Instruction.new self
end
inspect() click to toggle source
# File lib/rexml/instruction.rb, line 66
def inspect
  "<?p-i #{target} ...?>"
end
node_type() click to toggle source
# File lib/rexml/instruction.rb, line 62
def node_type
  :processing_instruction
end
write(writer, indent=-1, transitive=false, ie_hack=false) click to toggle source

DEPRECATED

See the rexml/formatters package

# File lib/rexml/instruction.rb, line 44
def write writer, indent=-1, transitive=false, ie_hack=false
  Kernel.warn( "#{self.class.name}.write is deprecated" )
  indent(writer, indent)
  writer << START.sub(/\/, '')
  writer << @target
  writer << ' '
  writer << @content
  writer << STOP.sub(/\/, '')
end


module REXML::Light - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::Light

In Files

  • lib/rexml/light/node.rb


class REXML::Light::Node - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Light::Node

Represents a tagged XML element. Elements are characterized by having children, attributes, and names, and can themselves be children.

In Files

  • lib/rexml/light/node.rb

Parent

Object

Constants

NAMESPLIT
PARENTS

Public Class Methods

new(node=nil) click to toggle source

Create a new element.

# File lib/rexml/light/node.rb, line 20
def initialize node=nil
  @node = node
  if node.kind_of? String
    node = [ :text, node ]
  elsif node.nil?
    node = [ :document, nil, nil ]
  elsif node[0] == :start_element
    node[0] = :element
  elsif node[0] == :start_doctype
    node[0] = :doctype
  elsif node[0] == :start_document
    node[0] = :document
  end
end

Public Instance Methods

<<(element) click to toggle source

Append a child to this element, optionally under a provided namespace. The namespace argument is ignored if the element argument is an Element object. Otherwise, the element argument is a string, the namespace (if provided) is the namespace the element is created in.

# File lib/rexml/light/node.rb, line 121
def << element
  if node_type() == :text
    at(-1) << element
  else
    newnode = Node.new( element )
    newnode.parent = self
    self.push( newnode )
  end
  at(-1)
end
=~( path ) click to toggle source
# File lib/rexml/light/node.rb, line 97
def =~( path )
  XPath.match( self, path )
end
[]( reference, ns=nil ) click to toggle source
# File lib/rexml/light/node.rb, line 85
def []( reference, ns=nil )
  if reference.kind_of? String
    pfx = ''
    pfx = "#{prefix(ns)}:" if ns
    at(3)["#{pfx}#{reference}"]
  elsif reference.kind_of? Range
    _old_get( Range.new(4+reference.begin, reference.end, reference.exclude_end?) )
  else
    _old_get( 4+reference )
  end
end
[]=( reference, ns, value=nil ) click to toggle source

Doesn't handle namespaces yet

# File lib/rexml/light/node.rb, line 102
def []=( reference, ns, value=nil )
  if reference.kind_of? String
    value = ns unless value
    at( 3 )[reference] = value
  elsif reference.kind_of? Range
    _old_put( Range.new(3+reference.begin, reference.end, reference.exclude_end?), ns )
  else
    if value
      _old_put( 4+reference, ns, value )
    else
      _old_put( 4+reference, ns )
    end
  end
end
children() click to toggle source
# File lib/rexml/light/node.rb, line 150
def children
  self
end
each() { |at(x+4)| ... } click to toggle source
# File lib/rexml/light/node.rb, line 43
def each
  size.times { |x| yield( at(x+4) ) }
end
has_name?( name, namespace = '' ) click to toggle source
# File lib/rexml/light/node.rb, line 146
def has_name?( name, namespace = '' )
  at(3) == name and namespace() == namespace
end
local_name() click to toggle source
# File lib/rexml/light/node.rb, line 61
def local_name
  namesplit
  @name
end
local_name=( name_str ) click to toggle source
# File lib/rexml/light/node.rb, line 66
def local_name=( name_str )
  _old_put( 1, "#@prefix:#{name_str}" )
end
name() click to toggle source
# File lib/rexml/light/node.rb, line 47
def name
  at(2)
end
name=( name_str, ns=nil ) click to toggle source
# File lib/rexml/light/node.rb, line 51
def name=( name_str, ns=nil )
  pfx = ''
  pfx = "#{prefix(ns)}:" if ns
  _old_put(2, "#{pfx}#{name_str}")
end
namespace( prefix=prefix() ) click to toggle source
# File lib/rexml/light/node.rb, line 74
def namespace( prefix=prefix() )
  namespace_of( self, prefix )
end
namespace=( namespace ) click to toggle source
# File lib/rexml/light/node.rb, line 78
def namespace=( namespace )
  @prefix = prefix( namespace )
  pfx = ''
  pfx = "#@prefix:" if @prefix.size > 0
  _old_put(1, "#{pfx}#@name")
end
node_type() click to toggle source
# File lib/rexml/light/node.rb, line 132
def node_type
  _old_get(0)
end
parent() click to toggle source
# File lib/rexml/light/node.rb, line 154
def parent
  at(1)
end
parent=( node ) click to toggle source
# File lib/rexml/light/node.rb, line 57
def parent=( node )
  _old_put(1,node)
end
prefix( namespace=nil ) click to toggle source
# File lib/rexml/light/node.rb, line 70
def prefix( namespace=nil )
  prefix_of( self, namespace )
end
root() click to toggle source
# File lib/rexml/light/node.rb, line 141
def root
  context = self
  context = context.at(1) while context.at(1)
end
size() click to toggle source
# File lib/rexml/light/node.rb, line 35
def size
  if PARENTS.include? @node[0]
    @node[-1].size
  else
    0
  end
end
text=( foo ) click to toggle source
# File lib/rexml/light/node.rb, line 136
def text=( foo )
  replace = at(4).kind_of?(String)? 1 : 0
  self._old_put(4,replace, normalizefoo)
end
to_s() click to toggle source
# File lib/rexml/light/node.rb, line 158
def to_s

end


module REXML::Namespace - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::Namespace

Adds named attributes to an object.

In Files

  • lib/rexml/namespace.rb

Included Modules

  • REXML::XMLTokens

Constants

NAMESPLIT

Attributes

expanded_name[R]

The name of the object, valid if set

local_name[R]

The name of the object, valid if set

name[R]

The name of the object, valid if set

prefix[RW]

The expanded name of the object, valid if name is set

Public Instance Methods

fully_expanded_name() click to toggle source

Fully expand the name, even if the prefix wasn't specified in the source file.

# File lib/rexml/namespace.rb, line 41
def fully_expanded_name
  ns = prefix
  return "#{ns}:#@name" if ns.size > 0
  return @name
end
has_name?( other, ns=nil ) click to toggle source

Compares names optionally WITH namespaces

# File lib/rexml/namespace.rb, line 27
def has_name?( other, ns=nil )
  if ns
    return (namespace() == ns and name() == other)
  elsif other.include? ":"
    return fully_expanded_name == other
  else
    return name == other
  end
end
name=( name ) click to toggle source

Sets the name and the expanded name

# File lib/rexml/namespace.rb, line 14
def name=( name )
  @expanded_name = name
  name =~ NAMESPLIT
  if $1
    @prefix = $1
  else
    @prefix = ""
    @namespace = ""
  end
  @name = $2
end


module REXML::Node - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::Node

Represents a node in the tree. Nodes are never encountered except as superclasses of other objects. Nodes have siblings.

In Files

  • lib/rexml/node.rb

Public Instance Methods

each_recursive() { |node| ... } click to toggle source

Visit all subnodes of self recursively

# File lib/rexml/node.rb, line 53
def each_recursive(&block) # :yields: node
  self.elements.each {|node|
    block.call(node)
    node.each_recursive(&block)
  }
end
find_first_recursive() { |node| ... } click to toggle source

Find (and return) first subnode (recursively) for which the block evaluates to true. Returns nil if none was found.

# File lib/rexml/node.rb, line 62
def find_first_recursive(&block) # :yields: node
  each_recursive {|node|
    return node if block.call(node)
  }
  return nil
end
indent(to, ind) click to toggle source
# File lib/rexml/node.rb, line 38
def indent to, ind
                    if @parent and @parent.context and not @parent.context[:indentstyle].nil? then
                            indentstyle = @parent.context[:indentstyle]
                    else
                            indentstyle = '  '
                    end
                    to << indentstyle*ind unless ind<1
end
index_in_parent() click to toggle source

Returns the position that self holds in its parent's array, indexed from 1.

# File lib/rexml/node.rb, line 71
def index_in_parent
  parent.index(self)+1
end
next_sibling_node() click to toggle source

@return the next sibling (nil if unset)

# File lib/rexml/node.rb, line 10
def next_sibling_node
  return nil if @parent.nil?
  @parent[ @parent.index(self) + 1 ]
end
parent?() click to toggle source
# File lib/rexml/node.rb, line 47
def parent?
  false;
end
previous_sibling_node() click to toggle source

@return the previous sibling (nil if unset)

# File lib/rexml/node.rb, line 16
def previous_sibling_node
  return nil if @parent.nil?
  ind = @parent.index(self)
  return nil if ind == 0
  @parent[ ind - 1 ]
end
to_s(indent=nil) click to toggle source
indent

DEPRECATED This parameter is now ignored. See the formatters in the REXML::Formatters package for changing the output style.

# File lib/rexml/node.rb, line 26
def to_s indent=nil
  unless indent.nil?
    Kernel.warn( "#{self.class.name}.to_s(indent) parameter is deprecated" )
    f = REXML::Formatters::Pretty.new( indent )
    f.write( self, rv = "" )
  else
    f = REXML::Formatters::Default.new
    f.write( self, rv = "" )
  end
  return rv
end


class REXML::NotationDecl - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::NotationDecl

In Files

  • lib/rexml/doctype.rb

Parent

REXML::Child

Attributes

public[RW]
system[RW]

Public Class Methods

new(name, middle, pub, sys) click to toggle source
# File lib/rexml/doctype.rb, line 242
def initialize name, middle, pub, sys
  super(nil)
  @name = name
  @middle = middle
  @public = pub
  @system = sys
end

Public Instance Methods

name() click to toggle source

This method retrieves the name of the notation.

Method contributed by Henrik Martensson

# File lib/rexml/doctype.rb, line 265
def name
  @name
end
to_s() click to toggle source
# File lib/rexml/doctype.rb, line 250
def to_s
  notation = "<!NOTATION #{@name} #{@middle}"
  notation << " #{@public.inspect}" if @public
  notation << " #{@system.inspect}" if @system
  notation << ">"
  notation
end
write( output, indent=-1 ) click to toggle source
# File lib/rexml/doctype.rb, line 258
def write( output, indent=-1 )
  output << to_s
end


class REXML::Output - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Output

In Files

  • lib/rexml/output.rb

Parent

Object

Included Modules

  • REXML::Encoding

Attributes

encoding[R]

Public Class Methods

new(real_IO, encd="iso-8859-1") click to toggle source
# File lib/rexml/output.rb, line 9
def initialize real_IO, encd="iso-8859-1"
  @output = real_IO
  self.encoding = encd

  @to_utf = encoding != 'UTF-8'

  if encoding == "UTF-16"
    @output << "\ufeff".encode("UTF-16BE")
    self.encoding = "UTF-16BE"
  end
end

Public Instance Methods

<<( content ) click to toggle source
# File lib/rexml/output.rb, line 21
def <<( content )
  @output << (@to_utf ? self.encode(content) : content)
end
to_s() click to toggle source
# File lib/rexml/output.rb, line 25
def to_s
  "Output[#{encoding}]"
end


class REXML::Parent - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Parent

A parent has children, and has methods for accessing them. The Parent class is never encountered except as the superclass for some other object.

In Files

  • lib/rexml/parent.rb

Parent

REXML::Child

Included Modules

  • Enumerable

Public Class Methods

new(parent=nil) click to toggle source

Constructor @param parent if supplied, will be set as the parent of this object

# File lib/rexml/parent.rb, line 12
def initialize parent=nil
  super(parent)
  @children = []
end

Public Instance Methods

<<( object ) click to toggle source
Alias for: push
[]( index ) click to toggle source

Fetches a child at a given index @param index the Integer index of the child to fetch

# File lib/rexml/parent.rb, line 58
def []( index )
  @children[index]
end
[]=( *args ) click to toggle source

Set an index entry. See Array.[]= @param index the index of the element to set @param opt either the object to set, or an Integer length @param child if opt is an Integer, this is the child to set @return the parent (self)

# File lib/rexml/parent.rb, line 71
def []=( *args )
  args[-1].parent = self
  @children[*args[0..-2]] = args[-1]
end
add( object ) click to toggle source
# File lib/rexml/parent.rb, line 17
def add( object )
  #puts "PARENT GOTS #{size} CHILDREN"
  object.parent = self
  @children << object
  #puts "PARENT NOW GOTS #{size} CHILDREN"
  object
end
Also aliased as: push
children() click to toggle source
Alias for: to_a
deep_clone() click to toggle source

Deeply clones this object. This creates a complete duplicate of this Parent, including all descendants.

# File lib/rexml/parent.rb, line 149
def deep_clone
  cl = clone()
  each do |child|
    if child.kind_of? Parent
      cl << child.deep_clone
    else
      cl << child.clone
    end
  end
  cl
end
delete( object ) click to toggle source
# File lib/rexml/parent.rb, line 33
def delete( object )
  found = false
  @children.delete_if {|c| c.equal?(object) and found = true }
  object.parent = nil if found
  found ? object : nil
end
delete_at( index ) click to toggle source
# File lib/rexml/parent.rb, line 48
def delete_at( index )
  @children.delete_at index
end
delete_if( &block ) click to toggle source
# File lib/rexml/parent.rb, line 44
def delete_if( &block )
  @children.delete_if(&block)
end
each(&block) click to toggle source
# File lib/rexml/parent.rb, line 40
def each(&block)
  @children.each(&block)
end
Also aliased as: each_child
each_child(&block) click to toggle source
Alias for: each
each_index( &block ) click to toggle source
# File lib/rexml/parent.rb, line 52
def each_index( &block )
  @children.each_index(&block)
end
index( child ) click to toggle source

Fetches the index of a given child @param child the child to get the index of @return the index of the child, or nil if the object is not a child of this parent.

# File lib/rexml/parent.rb, line 124
def index( child )
  count = -1
  @children.find { |i| count += 1 ; i.hash == child.hash }
  count
end
insert_after( child1, child2 ) click to toggle source

Inserts an child after another child @param child1 this is either an xpath or an Element. If an Element, child2 will be inserted after child1 in the child list of the parent. If an xpath, child2 will be inserted after the first child to match the xpath. @param child2 the child to insert @return the parent (self)

# File lib/rexml/parent.rb, line 103
def insert_after( child1, child2 )
  if child1.kind_of? String
    child1 = XPath.first( self, child1 )
    child1.parent.insert_after child1, child2
  else
    ind = index(child1)+1
    child2.parent.delete(child2) if child2.parent
    @children[ind,0] = child2
    child2.parent = self
  end
  self
end
insert_before( child1, child2 ) click to toggle source

Inserts an child before another child @param child1 this is either an xpath or an Element. If an Element, child2 will be inserted before child1 in the child list of the parent. If an xpath, child2 will be inserted before the first child to match the xpath. @param child2 the child to insert @return the parent (self)

# File lib/rexml/parent.rb, line 83
def insert_before( child1, child2 )
  if child1.kind_of? String
    child1 = XPath.first( self, child1 )
    child1.parent.insert_before child1, child2
  else
    ind = index(child1)
    child2.parent.delete(child2) if child2.parent
    @children[ind,0] = child2
    child2.parent = self
  end
  self
end
length() click to toggle source
Alias for: size
parent?() click to toggle source
# File lib/rexml/parent.rb, line 163
def parent?
  true
end
push( object ) click to toggle source
Also aliased as: <<
Alias for: add
replace_child( to_replace, replacement ) click to toggle source

Replaces one child with another, making sure the nodelist is correct @param to_replace the child to replace (must be a Child) @param replacement the child to insert into the nodelist (must be a Child)

# File lib/rexml/parent.rb, line 141
def replace_child( to_replace, replacement )
  @children.map! {|c| c.equal?( to_replace ) ? replacement : c }
  to_replace.parent = nil
  replacement.parent = self
end
size() click to toggle source

@return the number of children of this parent

# File lib/rexml/parent.rb, line 131
def size
  @children.size
end
Also aliased as: length
to_a() click to toggle source
# File lib/rexml/parent.rb, line 116
def to_a
  @children.dup
end
Also aliased as: children
unshift( object ) click to toggle source
# File lib/rexml/parent.rb, line 28
def unshift( object )
  object.parent = self
  @children.unshift object
end


class REXML::ParseException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::ParseException

In Files

  • lib/rexml/parseexception.rb

Parent

RuntimeError

Attributes

continued_exception[RW]
parser[RW]
source[RW]

Public Class Methods

new( message, source=nil, parser=nil, exception=nil ) click to toggle source
# File lib/rexml/parseexception.rb, line 5
def initialize( message, source=nil, parser=nil, exception=nil )
  super(message)
  @source = source
  @parser = parser
  @continued_exception = exception
end

Public Instance Methods

context() click to toggle source
# File lib/rexml/parseexception.rb, line 47
def context
  @source.current_line
end
line() click to toggle source
# File lib/rexml/parseexception.rb, line 42
def line
  @source.current_line[2] if @source and defined? @source.current_line and
  @source.current_line
end
position() click to toggle source
# File lib/rexml/parseexception.rb, line 37
def position
  @source.current_line[0] if @source and defined? @source.current_line and
  @source.current_line
end
to_s() click to toggle source
# File lib/rexml/parseexception.rb, line 12
def to_s
  # Quote the original exception, if there was one
  if @continued_exception
    err = @continued_exception.inspect
    err << "\n"
    err << @continued_exception.backtrace.join("\n")
    err << "\n...\n"
  else
    err = ""
  end

  # Get the stack trace and error message
  err << super

  # Add contextual information
  if @source
    err << "\nLine: #{line}\n"
    err << "Position: #{position}\n"
    err << "Last 80 unconsumed characters:\n"
    err << @source.buffer[0..80].force_encoding("ASCII-8BIT").gsub(/\n/, ' ')
  end

  err
end


module REXML::Parsers - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::Parsers

In Files

  • lib/rexml/parsers/baseparser.rb
  • lib/rexml/parsers/lightparser.rb
  • lib/rexml/parsers/pullparser.rb
  • lib/rexml/parsers/sax2parser.rb
  • lib/rexml/parsers/streamparser.rb
  • lib/rexml/parsers/treeparser.rb
  • lib/rexml/parsers/ultralightparser.rb
  • lib/rexml/parsers/xpathparser.rb


class REXML::Parsers::BaseParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Parsers::BaseParser

Using the Pull Parser

This API is experimental, and subject to change.

parser = PullParser.new( "<a>text<b att='val'/>txet</a>" )
while parser.has_next?
  res = parser.next
  puts res[1]['att'] if res.start_tag? and res[0] == 'b'
end

See the PullEvent class for information on the content of the results. The data is identical to the arguments passed for the various events to the StreamListener API.

Notice that:

parser = PullParser.new( "<a>BAD DOCUMENT" )
while parser.has_next?
  res = parser.next
  raise res[1] if res.error?
end

Nat Price gave me some good ideas for the API.

In Files

  • lib/rexml/parsers/baseparser.rb

Parent

Object

Constants

ATTDEF
ATTDEF_RE
ATTLISTDECL_PATTERN
ATTLISTDECL_START
ATTRIBUTE_PATTERN
ATTTYPE
ATTVALUE
CDATA_END
CDATA_PATTERN
CDATA_START
CLOSE_MATCH
COMBININGCHAR
COMMENT_PATTERN
COMMENT_START
DEFAULTDECL
DEFAULT_ENTITIES
DIGIT
DOCTYPE_PATTERN
DOCTYPE_START
ELEMENTDECL_PATTERN
ELEMENTDECL_START
ENCODING
ENTITYDECL
ENTITYDEF
ENTITYVALUE
ENTITY_START
ENUMERATEDTYPE
ENUMERATION
EREFERENCE
EXTENDER
EXTERNALID
GEDECL
IDENTITY
INSTRUCTION_PATTERN
INSTRUCTION_START
LETTER
MISSING_ATTRIBUTE_QUOTES

These are patterns to identify common markup errors, to make the error messages more informative.

NAME
NAMECHAR
NAME_STR
NCNAME_STR
NDATADECL
NMTOKEN
NMTOKENS
NOTATIONDECL_START
NOTATIONTYPE
PEDECL
PEDEF
PEREFERENCE
PUBIDCHAR

Entity constants

PUBIDLITERAL
PUBLIC
REFERENCE
REFERENCE_RE
STANDALONE
SYSTEM
SYSTEMENTITY
SYSTEMLITERAL
TAG_MATCH
TEXT_PATTERN
UNAME_STR
VERSION
XMLDECL_PATTERN
XMLDECL_START

Attributes

source[R]

Public Class Methods

new( source ) click to toggle source
# File lib/rexml/parsers/baseparser.rb, line 115
def initialize( source )
  self.stream = source
  @listeners = []
end

Public Instance Methods

add_listener( listener ) click to toggle source
# File lib/rexml/parsers/baseparser.rb, line 120
def add_listener( listener )
  @listeners << listener
end
empty?() click to toggle source

Returns true if there are no more events

# File lib/rexml/parsers/baseparser.rb, line 146
def empty?
  return (@source.empty? and @stack.empty?)
end
entity( reference, entities ) click to toggle source
# File lib/rexml/parsers/baseparser.rb, line 446
def entity( reference, entities )
  value = nil
  value = entities[ reference ] if entities
  if not value
    value = DEFAULT_ENTITIES[ reference ]
    value = value[2] if value
  end
  unnormalize( value, entities ) if value
end
has_next?() click to toggle source

Returns true if there are more events. Synonymous with !empty?

# File lib/rexml/parsers/baseparser.rb, line 151
def has_next?
  return !(@source.empty? and @stack.empty?)
end
normalize( input, entities=nil, entity_filter=nil ) click to toggle source

Escapes all possible entities

# File lib/rexml/parsers/baseparser.rb, line 457
def normalize( input, entities=nil, entity_filter=nil )
  copy = input.clone
  # Doing it like this rather than in a loop improves the speed
  copy.gsub!( EREFERENCE, '&amp;' )
  entities.each do |key, value|
    copy.gsub!( value, "&#{key};" ) unless entity_filter and
                                entity_filter.include?(entity)
  end if entities
  copy.gsub!( EREFERENCE, '&amp;' )
  DEFAULT_ENTITIES.each do |key, value|
    copy.gsub!( value[3], value[1] )
  end
  copy
end
peek(depth=0) click to toggle source

Peek at the depth event in the stack. The first element on the stack is at depth 0. If depth is -1, will parse to the end of the input stream and return the last event, which is always :end_document. Be aware that this causes the stream to be parsed up to the depth event, so you can effectively pre-parse the entire document (pull the entire thing into memory) using this method.

# File lib/rexml/parsers/baseparser.rb, line 167
def peek depth=0
  raise %Q[Illegal argument "#{depth}"] if depth < -1
  temp = []
  if depth == -1
    temp.push(pull()) until empty?
  else
    while @stack.size+temp.size < depth+1
      temp.push(pull())
    end
  end
  @stack += temp if temp.size > 0
  @stack[depth]
end
position() click to toggle source
# File lib/rexml/parsers/baseparser.rb, line 136
def position
  if @source.respond_to? :position
    @source.position
  else
    # FIXME
    0
  end
end
pull() click to toggle source

Returns the next event. This is a PullEvent object.

# File lib/rexml/parsers/baseparser.rb, line 182
def pull
  pull_event.tap do |event|
    @listeners.each do |listener|
      listener.receive event
    end
  end
end
stream=( source ) click to toggle source
# File lib/rexml/parsers/baseparser.rb, line 126
def stream=( source )
  @source = SourceFactory.create_from( source )
  @closed = nil
  @document_status = nil
  @tags = []
  @stack = []
  @entities = []
  @nsstack = []
end
unnormalize( string, entities=nil, filter=nil ) click to toggle source

Unescapes all possible entities

# File lib/rexml/parsers/baseparser.rb, line 473
def unnormalize( string, entities=nil, filter=nil )
  rv = string.clone
  rv.gsub!( /\r\n?/, "\n" )
  matches = rv.scan( REFERENCE_RE )
  return rv if matches.size == 0
  rv.gsub!( /&#0*((?:\d+)|(?:x[a-fA-F0-9]+));/ ) {
    m=$1
    m = "0#{m}" if m[0] == x
    [Integer(m)].pack('U*')
  }
  matches.collect!{|x|x[0]}.compact!
  if matches.size > 0
    matches.each do |entity_reference|
      unless filter and filter.include?(entity_reference)
        entity_value = entity( entity_reference, entities )
        if entity_value
          re = /&#{entity_reference};/
          rv.gsub!( re, entity_value )
        else
          er = DEFAULT_ENTITIES[entity_reference]
          rv.gsub!( er[0], er[2] ) if er
        end
      end
    end
    rv.gsub!( /&amp;/, '&' )
  end
  rv
end
unshift(token) click to toggle source

Push an event back on the head of the stream. This method has (theoretically) infinite depth.

# File lib/rexml/parsers/baseparser.rb, line 157
def unshift token
  @stack.unshift(token)
end


class REXML::Parsers::LightParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Parsers::LightParser

In Files

  • lib/rexml/parsers/lightparser.rb

Parent

Object

Public Class Methods

new(stream) click to toggle source
# File lib/rexml/parsers/lightparser.rb, line 8
def initialize stream
  @stream = stream
  @parser = REXML::Parsers::BaseParser.new( stream )
end

Public Instance Methods

add_listener( listener ) click to toggle source
# File lib/rexml/parsers/lightparser.rb, line 13
def add_listener( listener )
  @parser.add_listener( listener )
end
parse() click to toggle source
# File lib/rexml/parsers/lightparser.rb, line 22
def parse
  root = context = [ :document ]
  while true
    event = @parser.pull
    case event[0]
    when :end_document
      break
    when :start_element, :start_doctype
      new_node = event
      context << new_node
      new_node[1,0] = [context]
      context = new_node
    when :end_element, :end_doctype
      context = context[1]
    else
      new_node = event
      context << new_node
      new_node[1,0] = [context]
    end
  end
  root
end
rewind() click to toggle source
# File lib/rexml/parsers/lightparser.rb, line 17
def rewind
  @stream.rewind
  @parser.stream = @stream
end


class REXML::Parsers::PullEvent - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Parsers::PullEvent

A parsing event. The contents of the event are accessed as an +Array?, and the type is given either by the …? methods, or by accessing the type accessor. The contents of this object vary from event to event, but are identical to the arguments passed to +StreamListener+s for each event.

In Files

  • lib/rexml/parsers/pullparser.rb

Parent

Object

Public Class Methods

new(arg) click to toggle source

The type of this event. Will be one of :tag_start, :tag_end, :text, :processing_instruction, :comment, :doctype, :attlistdecl, :entitydecl, :notationdecl, :entity, :cdata, :xmldecl, or :error.

# File lib/rexml/parsers/pullparser.rb, line 94
def initialize(arg)
  @contents = arg
end

Public Instance Methods

[]( start, endd=nil) click to toggle source
# File lib/rexml/parsers/pullparser.rb, line 98
def []( start, endd=nil)
  if start.kind_of? Range
    @contents.slice( start.begin+1 .. start.end )
  elsif start.kind_of? Numeric
    if endd.nil?
      @contents.slice( start+1 )
    else
      @contents.slice( start+1, endd )
    end
  else
    raise "Illegal argument #{start.inspect} (#{start.class})"
  end
end
attlistdecl?() click to toggle source

Content: [ String text ]

# File lib/rexml/parsers/pullparser.rb, line 147
def attlistdecl?
  @contents[0] == :attlistdecl
end
cdata?() click to toggle source

Content: [ String text ]

# File lib/rexml/parsers/pullparser.rb, line 178
def cdata?
  @contents[0] == :cdata
end
comment?() click to toggle source

Content: [ String text ]

# File lib/rexml/parsers/pullparser.rb, line 137
def comment?
  @contents[0] == :comment
end
doctype?() click to toggle source

Content: [ String name, String pub_sys, String long_name, String uri ]

# File lib/rexml/parsers/pullparser.rb, line 142
def doctype?
  @contents[0] == :start_doctype
end
elementdecl?() click to toggle source

Content: [ String text ]

# File lib/rexml/parsers/pullparser.rb, line 152
def elementdecl?
  @contents[0] == :elementdecl
end
end_element?() click to toggle source

Content: [ String tag_name ]

# File lib/rexml/parsers/pullparser.rb, line 122
def end_element?
  @contents[0] == :end_element
end
entity?() click to toggle source

Content: [ String text ]

# File lib/rexml/parsers/pullparser.rb, line 173
def entity?
  @contents[0] == :entity
end
entitydecl?() click to toggle source

Due to the wonders of DTDs, an entity declaration can be just about anything. There's no way to normalize it; you'll have to interpret the content yourself. However, the following is true:

  • If the entity declaration is an internal entity:

    String name, String value

Content: [ String text ]

# File lib/rexml/parsers/pullparser.rb, line 163
def entitydecl?
  @contents[0] == :entitydecl
end
error?() click to toggle source
# File lib/rexml/parsers/pullparser.rb, line 187
def error?
  @contents[0] == :error
end
event_type() click to toggle source
# File lib/rexml/parsers/pullparser.rb, line 112
def event_type
  @contents[0]
end
inspect() click to toggle source
# File lib/rexml/parsers/pullparser.rb, line 191
def inspect
  @contents[0].to_s + ": " + @contents[1..-1].inspect
end
instruction?() click to toggle source

Content: [ String text ]

# File lib/rexml/parsers/pullparser.rb, line 132
def instruction?
  @contents[0] == :processing_instruction
end
notationdecl?() click to toggle source

Content: [ String text ]

# File lib/rexml/parsers/pullparser.rb, line 168
def notationdecl?
  @contents[0] == :notationdecl
end
start_element?() click to toggle source

Content: [ String tag_name, Hash attributes ]

# File lib/rexml/parsers/pullparser.rb, line 117
def start_element?
  @contents[0] == :start_element
end
text?() click to toggle source

Content: [ String raw_text, String unnormalized_text ]

# File lib/rexml/parsers/pullparser.rb, line 127
def text?
  @contents[0] == :text
end
xmldecl?() click to toggle source

Content: [ String version, String encoding, String standalone ]

# File lib/rexml/parsers/pullparser.rb, line 183
def xmldecl?
  @contents[0] == :xmldecl
end


class REXML::Parsers::PullParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Parsers::PullParser

Using the Pull Parser

This API is experimental, and subject to change.

parser = PullParser.new( "<a>text<b att='val'/>txet</a>" )
while parser.has_next?
  res = parser.next
  puts res[1]['att'] if res.start_tag? and res[0] == 'b'
end

See the PullEvent class for information on the content of the results. The data is identical to the arguments passed for the various events to the StreamListener API.

Notice that:

parser = PullParser.new( "<a>BAD DOCUMENT" )
while parser.has_next?
  res = parser.next
  raise res[1] if res.error?
end

Nat Price gave me some good ideas for the API.

In Files

  • lib/rexml/parsers/pullparser.rb

Parent

Object

Included Modules

  • REXML::XMLTokens

Public Class Methods

new(stream) click to toggle source
# File lib/rexml/parsers/pullparser.rb, line 37
def initialize stream
  @entities = {}
  @listeners = nil
  @parser = BaseParser.new( stream )
  @my_stack = []
end

Public Instance Methods

add_listener( listener ) click to toggle source
# File lib/rexml/parsers/pullparser.rb, line 44
def add_listener( listener )
  @listeners = [] unless @listeners
  @listeners << listener
end
each() { |pull| ... } click to toggle source
# File lib/rexml/parsers/pullparser.rb, line 49
def each
  while has_next?
    yield self.pull
  end
end
peek(depth=0) click to toggle source
# File lib/rexml/parsers/pullparser.rb, line 55
def peek depth=0
  if @my_stack.length <= depth
    (depth - @my_stack.length + 1).times {
      e = PullEvent.new(@parser.pull)
      @my_stack.push(e)
    }
  end
  @my_stack[depth]
end
pull() click to toggle source
# File lib/rexml/parsers/pullparser.rb, line 65
def pull
  return @my_stack.shift if @my_stack.length > 0

  event = @parser.pull
  case event[0]
  when :entitydecl
    @entities[ event[1] ] =
      event[2] unless event[2] =~ /PUBLIC|SYSTEM/
  when :text
    unnormalized = @parser.unnormalize( event[1], @entities )
    event << unnormalized
  end
  PullEvent.new( event )
end
unshift(token) click to toggle source
# File lib/rexml/parsers/pullparser.rb, line 80
def unshift token
  @my_stack.unshift token
end


class REXML::Parsers::SAX2Parser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Parsers::SAX2Parser

SAX2Parser

In Files

  • lib/rexml/parsers/sax2parser.rb

Parent

Object

Public Class Methods

new(source) click to toggle source
# File lib/rexml/parsers/sax2parser.rb, line 10
def initialize source
  @parser = BaseParser.new(source)
  @listeners = []
  @procs = []
  @namespace_stack = []
  @has_listeners = false
  @tag_stack = []
  @entities = {}
end

Public Instance Methods

add_listener( listener ) click to toggle source
# File lib/rexml/parsers/sax2parser.rb, line 24
def add_listener( listener )
  @parser.add_listener( listener )
end
deafen( listener=nil, &blok ) click to toggle source
# File lib/rexml/parsers/sax2parser.rb, line 76
def deafen( listener=nil, &blok )
  if listener
    @listeners.delete_if {|item| item[-1] == listener }
    @has_listeners = false if @listeners.size == 0
  else
    @procs.delete_if {|item| item[-1] == blok }
  end
end
listen( *args, &blok ) click to toggle source

Listen arguments:

Symbol, Array, Block

Listen to Symbol events on Array elements

Symbol, Block

Listen to Symbol events

Array, Listener

Listen to all events on Array elements

Array, Block

Listen to :start_element events on Array elements

Listener

Listen to All events

Symbol can be one of: :start_element, :end_element, :start_prefix_mapping, :end_prefix_mapping, :characters, :processing_instruction, :doctype, :attlistdecl, :elementdecl, :entitydecl, :notationdecl, :cdata, :xmldecl, :comment

There is an additional symbol that can be listened for: :progress. This will be called for every event generated, passing in the current stream position.

Array contains regular expressions or strings which will be matched against fully qualified element names.

Listener must implement the methods in SAX2Listener

Block will be passed the same arguments as a SAX2Listener method would be, where the method name is the same as the matched Symbol. See the SAX2Listener for more information.

# File lib/rexml/parsers/sax2parser.rb, line 58
def listen( *args, &blok )
  if args[0].kind_of? Symbol
    if args.size == 2
      args[1].each { |match| @procs << [args[0], match, blok] }
    else
      add( [args[0], nil, blok] )
    end
  elsif args[0].kind_of? Array
    if args.size == 2
      args[0].each { |match| add( [nil, match, args[1]] ) }
    else
      args[0].each { |match| add( [ :start_element, match, blok ] ) }
    end
  else
    add([nil, nil, args[0]])
  end
end
parse() click to toggle source
# File lib/rexml/parsers/sax2parser.rb, line 85
def parse
  @procs.each { |sym,match,block| block.call if sym == :start_document }
  @listeners.each { |sym,match,block|
    block.start_document if sym == :start_document or sym.nil?
  }
  context = []
  while true
    event = @parser.pull
    case event[0]
    when :end_document
      handle( :end_document )
      break
    when :start_doctype
      handle( :doctype, *event[1..-1])
    when :end_doctype
      context = context[1]
    when :start_element
      @tag_stack.push(event[1])
      # find the observers for namespaces
      procs = get_procs( :start_prefix_mapping, event[1] )
      listeners = get_listeners( :start_prefix_mapping, event[1] )
      if procs or listeners
        # break out the namespace declarations
        # The attributes live in event[2]
        event[2].each {|n, v| event[2][n] = @parser.normalize(v)}
        nsdecl = event[2].find_all { |n, value| n =~ /^xmlns(:|$)/ }
        nsdecl.collect! { |n, value| [ n[6..-1], value ] }
        @namespace_stack.push({})
        nsdecl.each do |n,v|
          @namespace_stack[-1][n] = v
          # notify observers of namespaces
          procs.each { |ob| ob.call( n, v ) } if procs
          listeners.each { |ob| ob.start_prefix_mapping(n, v) } if listeners
        end
      end
      event[1] =~ Namespace::NAMESPLIT
      prefix = $1
      local = $2
      uri = get_namespace(prefix)
      # find the observers for start_element
      procs = get_procs( :start_element, event[1] )
      listeners = get_listeners( :start_element, event[1] )
      # notify observers
      procs.each { |ob| ob.call( uri, local, event[1], event[2] ) } if procs
      listeners.each { |ob|
        ob.start_element( uri, local, event[1], event[2] )
      } if listeners
    when :end_element
      @tag_stack.pop
      event[1] =~ Namespace::NAMESPLIT
      prefix = $1
      local = $2
      uri = get_namespace(prefix)
      # find the observers for start_element
      procs = get_procs( :end_element, event[1] )
      listeners = get_listeners( :end_element, event[1] )
      # notify observers
      procs.each { |ob| ob.call( uri, local, event[1] ) } if procs
      listeners.each { |ob|
        ob.end_element( uri, local, event[1] )
      } if listeners

      namespace_mapping = @namespace_stack.pop
      # find the observers for namespaces
      procs = get_procs( :end_prefix_mapping, event[1] )
      listeners = get_listeners( :end_prefix_mapping, event[1] )
      if procs or listeners
        namespace_mapping.each do |ns_prefix, ns_uri|
          # notify observers of namespaces
          procs.each { |ob| ob.call( ns_prefix ) } if procs
          listeners.each { |ob| ob.end_prefix_mapping(ns_prefix) } if listeners
        end
      end
    when :text
      #normalized = @parser.normalize( event[1] )
      #handle( :characters, normalized )
      copy = event[1].clone

      esub = proc { |match|
        if @entities.has_key?($1)
          @entities[$1].gsub(Text::REFERENCE, &esub)
        else
          match
        end
      }

      copy.gsub!( Text::REFERENCE, &esub )
      copy.gsub!( Text::NUMERICENTITY ) {|m|
        m=$1
        m = "0#{m}" if m[0] == x
        [Integer(m)].pack('U*')
      }
      handle( :characters, copy )
    when :entitydecl
      @entities[ event[1] ] = event[2] if event.size == 3
      handle( *event )
    when :processing_instruction, :comment, :attlistdecl,
      :elementdecl, :cdata, :notationdecl, :xmldecl
      handle( *event )
    end
    handle( :progress, @parser.position )
  end
end
source() click to toggle source
# File lib/rexml/parsers/sax2parser.rb, line 20
def source
  @parser.source
end


class REXML::Parsers::StreamParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Parsers::StreamParser

In Files

  • lib/rexml/parsers/streamparser.rb

Parent

Object

Public Class Methods

new(source, listener) click to toggle source
# File lib/rexml/parsers/streamparser.rb, line 4
def initialize source, listener
  @listener = listener
  @parser = BaseParser.new( source )
end

Public Instance Methods

add_listener( listener ) click to toggle source
# File lib/rexml/parsers/streamparser.rb, line 9
def add_listener( listener )
  @parser.add_listener( listener )
end
parse() click to toggle source
# File lib/rexml/parsers/streamparser.rb, line 13
def parse
  # entity string
  while true
    event = @parser.pull
    case event[0]
    when :end_document
      return
    when :start_element
      attrs = event[2].each do |n, v|
        event[2][n] = @parser.unnormalize( v )
      end
      @listener.tag_start( event[1], attrs )
    when :end_element
      @listener.tag_end( event[1] )
    when :text
      normalized = @parser.unnormalize( event[1] )
      @listener.text( normalized )
    when :processing_instruction
      @listener.instruction( *event[1,2] )
    when :start_doctype
      @listener.doctype( *event[1..-1] )
    when :end_doctype
      # FIXME: remove this condition for milestone:3.2
      @listener.doctype_end if @listener.respond_to? :doctype_end
    when :comment, :attlistdecl, :cdata, :xmldecl, :elementdecl
      @listener.send( event[0].to_s, *event[1..-1] )
    when :entitydecl, :notationdecl
      @listener.send( event[0].to_s, event[1..-1] )
    end
  end
end


class REXML::Parsers::TreeParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Parsers::TreeParser

In Files

  • lib/rexml/parsers/treeparser.rb

Parent

Object

Public Class Methods

new( source, build_context = Document.new ) click to toggle source
# File lib/rexml/parsers/treeparser.rb, line 7
def initialize( source, build_context = Document.new )
  @build_context = build_context
  @parser = Parsers::BaseParser.new( source )
end

Public Instance Methods

add_listener( listener ) click to toggle source
# File lib/rexml/parsers/treeparser.rb, line 12
def add_listener( listener )
  @parser.add_listener( listener )
end
parse() click to toggle source
# File lib/rexml/parsers/treeparser.rb, line 16
def parse
  tag_stack = []
  in_doctype = false
  entities = nil
  begin
    while true
      event = @parser.pull
      #STDERR.puts "TREEPARSER GOT #{event.inspect}"
      case event[0]
      when :end_document
        unless tag_stack.empty?
          #raise ParseException.new("No close tag for #{tag_stack.inspect}")
          raise ParseException.new("No close tag for #{@build_context.xpath}")
        end
        return
      when :start_element
        tag_stack.push(event[1])
        el = @build_context = @build_context.add_element( event[1] )
        event[2].each do |key, value|
          el.attributes[key]=Attribute.new(key,value,self)
        end
      when :end_element
        tag_stack.pop
        @build_context = @build_context.parent
      when :text
        if not in_doctype
          if @build_context[-1].instance_of? Text
            @build_context[-1] << event[1]
          else
            @build_context.add(
              Text.new(event[1], @build_context.whitespace, nil, true)
            ) unless (
              @build_context.ignore_whitespace_nodes and
              event[1].strip.size==0
            )
          end
        end
      when :comment
        c = Comment.new( event[1] )
        @build_context.add( c )
      when :cdata
        c = CData.new( event[1] )
        @build_context.add( c )
      when :processing_instruction
        @build_context.add( Instruction.new( event[1], event[2] ) )
      when :end_doctype
        in_doctype = false
        entities.each { |k,v| entities[k] = @build_context.entities[k].value }
        @build_context = @build_context.parent
      when :start_doctype
        doctype = DocType.new( event[1..-1], @build_context )
        @build_context = doctype
        entities = {}
        in_doctype = true
      when :attlistdecl
        n = AttlistDecl.new( event[1..-1] )
        @build_context.add( n )
      when :externalentity
        n = ExternalEntity.new( event[1] )
        @build_context.add( n )
      when :elementdecl
        n = ElementDecl.new( event[1] )
        @build_context.add(n)
      when :entitydecl
        entities[ event[1] ] = event[2] unless event[2] =~ /PUBLIC|SYSTEM/
        @build_context.add(Entity.new(event))
      when :notationdecl
        n = NotationDecl.new( *event[1..-1] )
        @build_context.add( n )
      when :xmldecl
        x = XMLDecl.new( event[1], event[2], event[3] )
        @build_context.add( x )
      end
    end
  rescue REXML::Validation::ValidationException
    raise
  rescue REXML::UndefinedNamespaceException
    raise
  rescue
    raise ParseException.new( $!.message, @parser.source, @parser, $! )
  end
end


class REXML::Parsers::UltraLightParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Parsers::UltraLightParser

In Files

  • lib/rexml/parsers/ultralightparser.rb

Parent

Object

Public Class Methods

new(stream) click to toggle source
# File lib/rexml/parsers/ultralightparser.rb, line 7
def initialize stream
  @stream = stream
  @parser = REXML::Parsers::BaseParser.new( stream )
end

Public Instance Methods

add_listener( listener ) click to toggle source
# File lib/rexml/parsers/ultralightparser.rb, line 12
def add_listener( listener )
  @parser.add_listener( listener )
end
parse() click to toggle source
# File lib/rexml/parsers/ultralightparser.rb, line 21
def parse
  root = context = []
  while true
    event = @parser.pull
    case event[0]
    when :end_document
      break
    when :end_doctype
      context = context[1]
    when :start_element, :doctype
      context << event
      event[1,0] = [context]
      context = event
    when :end_element
      context = context[1]
    else
      context << event
    end
  end
  root
end
rewind() click to toggle source
# File lib/rexml/parsers/ultralightparser.rb, line 16
def rewind
  @stream.rewind
  @parser.stream = @stream
end


class REXML::Parsers::XPathParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Parsers::XPathParser

You don't want to use this class. Really. Use XPath, which is a wrapper for this class. Believe me. You don't want to poke around in here. There is strange, dark magic at work in this code. Beware. Go back! Go back while you still can!

In Files

  • lib/rexml/parsers/xpathparser.rb

Parent

Object

Included Modules

  • REXML::XMLTokens

Constants

AXIS

RelativeLocationPath

|                                                    Step
  | (AXIS_NAME '::' | '@' | '')                     AxisSpecifier
    NodeTest
      Predicate
  | '.' | '..'                                      AbbreviatedStep
|  RelativeLocationPath '/' Step
| RelativeLocationPath '//' Step
LITERAL
NCNAMETEST
Returns a 1-1 map of the nodeset
The contents of the resulting array are either:
  true/false, if a positive match
  String, if a name match

NodeTest

| ('*' | NCNAME ':' '*' | QNAME)                NameTest
| NODE_TYPE '(' ')'                              NodeType
| PI '(' LITERAL ')'                            PI
  | '[' expr ']'                                Predicate
NODE_TYPE
NT
NUMBER
PI
QNAME
VARIABLE_REFERENCE

| VARIABLE_REFERENCE | '(' expr ')' | LITERAL | NUMBER | FunctionCall

Public Instance Methods

abbreviate( path ) click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 34
def abbreviate( path )
  path = path.kind_of?(String) ? parse( path ) : path
  string = ""
  document = false
  while path.size > 0
    op = path.shift
    case op
    when :node
    when :attribute
      string << "/" if string.size > 0
      string << "@"
    when :child
      string << "/" if string.size > 0
    when :descendant_or_self
      string << "/"
    when :self
      string << "."
    when :parent
      string << ".."
    when :any
      string << "*"
    when :text
      string << "text()"
    when :following, :following_sibling,
          :ancestor, :ancestor_or_self, :descendant,
          :namespace, :preceding, :preceding_sibling
      string << "/" unless string.size == 0
      string << op.to_s.tr("_", "-")
      string << "::"
    when :qname
      prefix = path.shift
      name = path.shift
      string << prefix+":" if prefix.size > 0
      string << name
    when :predicate
      string << '['
      string << predicate_to_string( path.shift ) {|x| abbreviate( x ) }
      string << ']'
    when :document
      document = true
    when :function
      string << path.shift
      string << "( "
      string << predicate_to_string( path.shift[0] ) {|x| abbreviate( x )}
      string << " )"
    when :literal
      string << %Q{ "#{path.shift}" }
    else
      string << "/" unless string.size == 0
      string << "UNKNOWN("
      string << op.inspect
      string << ")"
    end
  end
  string = "/"+string if document
  return string
end
expand( path ) click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 92
def expand( path )
  path = path.kind_of?(String) ? parse( path ) : path
  string = ""
  document = false
  while path.size > 0
    op = path.shift
    case op
    when :node
      string << "node()"
    when :attribute, :child, :following, :following_sibling,
          :ancestor, :ancestor_or_self, :descendant, :descendant_or_self,
          :namespace, :preceding, :preceding_sibling, :self, :parent
      string << "/" unless string.size == 0
      string << op.to_s.tr("_", "-")
      string << "::"
    when :any
      string << "*"
    when :qname
      prefix = path.shift
      name = path.shift
      string << prefix+":" if prefix.size > 0
      string << name
    when :predicate
      string << '['
      string << predicate_to_string( path.shift ) { |x| expand(x) }
      string << ']'
    when :document
      document = true
    else
      string << "/" unless string.size == 0
      string << "UNKNOWN("
      string << op.inspect
      string << ")"
    end
  end
  string = "/"+string if document
  return string
end
namespaces=( namespaces ) click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 14
def namespaces=( namespaces )
  Functions::namespace_context = namespaces
  @namespaces = namespaces
end
parse(path) click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 19
def parse path
  path = path.dup
  path.gsub!(/([\(\[])\s+/, '\1') # Strip ignorable spaces
  path.gsub!( /\s+([\]\)])/, '\1')
  parsed = []
  path = OrExpr(path, parsed)
  parsed
end
predicate(path) click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 28
def predicate path
  parsed = []
  Predicate( "[#{path}]", parsed )
  parsed
end
predicate_to_string( path ) { |path| ... } click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 131
def predicate_to_string( path, &block )
  string = ""
  case path[0]
  when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union
    op = path.shift
    case op
    when :eq
      op = "="
    when :lt
      op = "<"
    when :gt
      op = ">"
    when :lteq
      op = "<="
    when :gteq
      op = ">="
    when :neq
      op = "!="
    when :union
      op = "|"
    end
    left = predicate_to_string( path.shift, &block )
    right = predicate_to_string( path.shift, &block )
    string << " "
    string << left
    string << " "
    string << op.to_s
    string << " "
    string << right
    string << " "
  when :function
    path.shift
    name = path.shift
    string << name
    string << "( "
    string << predicate_to_string( path.shift, &block )
    string << " )"
  when :literal
    path.shift
    string << " "
    string << path.shift.inspect
    string << " "
  else
    string << " "
    string << yield( path )
    string << " "
  end
  return string.squeeze(" ")
end


class REXML::QuickPath - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::QuickPath

In Files

  • lib/rexml/quickpath.rb

Parent

Object

Included Modules

  • REXML::Functions
  • REXML::XMLTokens

Constants

EMPTY_HASH

A base Hash object to be used when initializing a default empty namespaces set.

OPERAND_

Public Class Methods

attribute( name ) click to toggle source
# File lib/rexml/quickpath.rb, line 205
def QuickPath::attribute( name )
  return Functions.node.attributes[name] if Functions.node.kind_of? Element
end
axe( elements, axe_name, rest ) click to toggle source
# File lib/rexml/quickpath.rb, line 105
def QuickPath::axe( elements, axe_name, rest )
  matches = []
  matches = filter( elements.dup, rest ) if axe_name =~ /-or-self$/
  case axe_name
  when /^descendant/
    elements.each do |element|
      matches |= filter( element.to_a, "descendant-or-self::#{rest}" ) if element.kind_of? Element
    end
  when /^ancestor/
    elements.each do |element|
      while element.parent
        matches << element.parent
        element = element.parent
      end
    end
    matches = filter( matches, rest )
  when "self"
    matches = filter( elements, rest )
  when "child"
    elements.each do |element|
      matches |= filter( element.to_a, rest ) if element.kind_of? Element
    end
  when "attribute"
    elements.each do |element|
      matches << element.attributes[ rest ] if element.kind_of? Element
    end
  when "parent"
    matches = filter(elements.collect{|element| element.parent}.uniq, rest)
  when "following-sibling"
    matches = filter(elements.collect{|element| element.next_sibling}.uniq,
      rest)
  when "previous-sibling"
    matches = filter(elements.collect{|element|
      element.previous_sibling}.uniq, rest )
  end
  return matches.uniq
end
each(element, path, namespaces=EMPTY_HASH, &block) click to toggle source
# File lib/rexml/quickpath.rb, line 17
def QuickPath::each element, path, namespaces=EMPTY_HASH, &block
  path = "*" unless path
  match(element, path, namespaces).each( &block )
end
filter(elements, path) click to toggle source

Given an array of nodes it filters the array based on the path. The result is that when this method returns, the array will contain elements which match the path

# File lib/rexml/quickpath.rb, line 49
def QuickPath::filter elements, path
  return elements if path.nil? or path == '' or elements.size == 0
  case path
  when /^\/\//                                                                                     # Descendant
    return axe( elements, "descendant-or-self", $' )
  when /^\/?\b(\w[-\w]*)\b::/                                                      # Axe
    return axe( elements, $1, $' )
  when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/      # Child
    rest = $'
    results = []
    elements.each do |element|
      results |= filter( element.to_a, rest )
    end
    return results
  when /^\/?(\w[-\w]*)\(/                                                  # / Function
    return function( elements, $1, $' )
  when Namespace::NAMESPLIT         # Element name
    name = $2
    ns = $1
    rest = $'
    elements.delete_if do |element|
      !(element.kind_of? Element and
        (element.expanded_name == name or
         (element.name == name and
          element.namespace == Functions.namespace_context[ns])))
    end
    return filter( elements, rest )
  when /^\/\[/
    matches = []
    elements.each do |element|
      matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element
    end
    return matches
  when /^\[/                                                                                               # Predicate
    return predicate( elements, path )
  when /^\/?\.\.\./                                                                                # Ancestor
    return axe( elements, "ancestor", $' )
  when /^\/?\.\./                                                                                  # Parent
    return filter( elements.collect{|e|e.parent}, $' )
  when /^\/?\./                                                                                            # Self
    return filter( elements, $' )
  when /^\*/                                                                                                       # Any
    results = []
    elements.each do |element|
      results |= filter( [element], $' ) if element.kind_of? Element
      #if element.kind_of? Element
      #     children = element.to_a
      #     children.delete_if { |child| !child.kind_of?(Element) }
      #     results |= filter( children, $' )
      #end
    end
    return results
  end
  return []
end
first(element, path, namespaces=EMPTY_HASH) click to toggle source
# File lib/rexml/quickpath.rb, line 13
def QuickPath::first element, path, namespaces=EMPTY_HASH
  match(element, path, namespaces)[0]
end
function( elements, fname, rest ) click to toggle source
# File lib/rexml/quickpath.rb, line 221
def QuickPath::function( elements, fname, rest )
  args = parse_args( elements, rest )
  Functions.pair = [0, elements.size]
  results = []
  elements.each do |element|
    Functions.pair[0] += 1
    Functions.node = element
    res = Functions.send( fname, *args )
    case res
    when true
      results << element
    when Fixnum
      results << element if Functions.pair[0] == res
    end
  end
  return results
end
match(element, path, namespaces=EMPTY_HASH) click to toggle source
# File lib/rexml/quickpath.rb, line 22
def QuickPath::match element, path, namespaces=EMPTY_HASH
  raise "nil is not a valid xpath" unless path
  results = nil
  Functions::namespace_context = namespaces
  case path
  when /^\/([^\/]|$)/
    # match on root
    path = path[1..-1]
    return [element.root.parent] if path == ''
    results = filter([element.root], path)
  when /^[-\w]*::/
    results = filter([element], path)
  when /^\*/
    results = filter(element.to_a, path)
  when /^[\[!\w:]/
    # match on child
    children = element.to_a
    results = filter(children, path)
  else
    results = filter([element], path)
  end
  return results
end
method_missing( id, *args ) click to toggle source
# File lib/rexml/quickpath.rb, line 213
def QuickPath::method_missing( id, *args )
  begin
    Functions.send( id.id2name, *args )
  rescue Exception
    raise "METHOD: #{id.id2name}(#{args.join ', '})\n#{$!.message}"
  end
end
name() click to toggle source
# File lib/rexml/quickpath.rb, line 209
def QuickPath::name()
  return Functions.node.name if Functions.node.kind_of? Element
end
parse_args( element, string ) click to toggle source
# File lib/rexml/quickpath.rb, line 239
def QuickPath::parse_args( element, string )
  # /.*?(?:\)|,)/
  arguments = []
  buffer = ""
  while string and string != ""
    c = string[0]
    string.sub!(/^./, "")
    case c
    when ,
      # if depth = 1, then we start a new argument
      arguments << evaluate( buffer )
      #arguments << evaluate( string[0..count] )
    when (
      # start a new method call
      function( element, buffer, string )
      buffer = ""
    when )
      # close the method call and return arguments
      return arguments
    else
      buffer << c
    end
  end
  ""
end
predicate( elements, path ) click to toggle source

A predicate filters a node-set with respect to an axis to produce a new node-set. For each node in the node-set to be filtered, the PredicateExpr is evaluated with that node as the context node, with the number of nodes in the node-set as the context size, and with the proximity position of the node in the node-set with respect to the axis as the context position; if PredicateExpr evaluates to true for that node, the node is included in the new node-set; otherwise, it is not included.

A PredicateExpr is evaluated by evaluating the Expr and converting the result to a boolean. If the result is a number, the result will be converted to true if the number is equal to the context position and will be converted to false otherwise; if the result is not a number, then the result will be converted as if by a call to the boolean function. Thus a location path para is equivalent to para.

# File lib/rexml/quickpath.rb, line 160
def QuickPath::predicate( elements, path )
  ind = 1
  bcount = 1
  while bcount > 0
    bcount += 1 if path[ind] == [
    bcount -= 1 if path[ind] == ]
    ind += 1
  end
  ind -= 1
  predicate = path[1..ind-1]
  rest = path[ind+1..-1]

  # have to change 'a [=<>] b [=<>] c' into 'a [=<>] b and b [=<>] c'
  #
  predicate.gsub!(
    /#{OPERAND_}\s*([<>=])\s*#{OPERAND_}\s*([<>=])\s*#{OPERAND_}/,
    '\1 \2 \3 and \3 \4 \5' )
  # Let's do some Ruby trickery to avoid some work:
  predicate.gsub!( /&/, "&&" )
  predicate.gsub!( /=/, "==" )
  predicate.gsub!( /@(\w[-\w.]*)/, 'attribute("\1")' )
  predicate.gsub!( /\bmod\b/, "%" )
  predicate.gsub!( /\b(\w[-\w.]*\()/ ) {
    fname = $1
    fname.gsub( /-/, "_" )
  }

  Functions.pair = [ 0, elements.size ]
  results = []
  elements.each do |element|
    Functions.pair[0] += 1
    Functions.node = element
    res = eval( predicate )
    case res
    when true
      results << element
    when Fixnum
      results << element if Functions.pair[0] == res
    when String
      results << element
    end
  end
  return filter( results, rest )
end


module REXML::SAX2Listener - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::SAX2Listener

A template for stream parser listeners. Note that the declarations (attlistdecl, elementdecl, etc) are trivially processed; REXML doesn't yet handle doctype entity declarations, so you have to parse them out yourself.

Missing methods from SAX2

ignorable_whitespace

Methods extending SAX2

WARNING These methods are certainly going to change, until DTDs are fully supported. Be aware of this.

start_document
end_document
doctype
elementdecl
attlistdecl
entitydecl
notationdecl
cdata
xmldecl
comment

In Files

  • lib/rexml/sax2listener.rb

Public Instance Methods

attlistdecl(element, pairs, contents) click to toggle source

If a doctype includes an ATTLIST declaration, it will cause this method to be called. The content is the declaration itself, unparsed. EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as “el attr CDATA #REQUIRED”. This is the same for all of the .*decl methods.

# File lib/rexml/sax2listener.rb, line 52
def attlistdecl(element, pairs, contents)
end
cdata(content) click to toggle source

Called when <![CDATA[ … ]]> is encountered in a document. @p content “…”

# File lib/rexml/sax2listener.rb, line 80
def cdata content
end
characters(text) click to toggle source
# File lib/rexml/sax2listener.rb, line 35
def characters text
end
comment(comment) click to toggle source

Called when a comment is encountered. @p comment The content of the comment

# File lib/rexml/sax2listener.rb, line 92
def comment comment
end
doctype(name, pub_sys, long_name, uri) click to toggle source

Handles a doctype declaration. Any attributes of the doctype which are not supplied will be nil. # EG, <!DOCTYPE me PUBLIC “foo” “bar”> @p name the name of the doctype; EG, “me” @p pub_sys “PUBLIC”, “SYSTEM”, or nil. EG, “PUBLIC” @p long_name the supplied long name, or nil. EG, “foo” @p uri the uri of the doctype, or nil. EG, “bar”

# File lib/rexml/sax2listener.rb, line 45
def doctype name, pub_sys, long_name, uri
end
elementdecl(content) click to toggle source

<!ELEMENT …>

# File lib/rexml/sax2listener.rb, line 55
def elementdecl content
end
end_document() click to toggle source
# File lib/rexml/sax2listener.rb, line 25
def end_document
end
end_element(uri, localname, qname) click to toggle source
# File lib/rexml/sax2listener.rb, line 33
def end_element uri, localname, qname
end
end_prefix_mapping(prefix) click to toggle source
# File lib/rexml/sax2listener.rb, line 29
def end_prefix_mapping prefix
end
entitydecl(name, decl) click to toggle source

<!ENTITY …> The argument passed to this method is an array of the entity declaration. It can be in a number of formats, but in general it returns (example, result):

<!ENTITY % YN '"Yes"'>
["%", "YN", "'\"Yes\"'", "\""]
<!ENTITY % YN 'Yes'>
["%", "YN", "'Yes'", "s"]
<!ENTITY WhatHeSaid "He said %YN;">
["WhatHeSaid", "\"He said %YN;\"", "YN"]
<!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
["open-hatch", "SYSTEM", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
<!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
["open-hatch", "PUBLIC", "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\"", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
<!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif>
["hatch-pic", "SYSTEM", "\"../grafix/OpenHatch.gif\"", "\n\t\t\t\t\t\t\tNDATA gif", "gif"]
# File lib/rexml/sax2listener.rb, line 73
def entitydecl name, decl
end
notationdecl(content) click to toggle source

<!NOTATION …>

# File lib/rexml/sax2listener.rb, line 76
def notationdecl content
end
processing_instruction(target, data) click to toggle source
# File lib/rexml/sax2listener.rb, line 37
def processing_instruction target, data
end
progress(position) click to toggle source
# File lib/rexml/sax2listener.rb, line 94
def progress position
end
start_document() click to toggle source
# File lib/rexml/sax2listener.rb, line 23
def start_document
end
start_element(uri, localname, qname, attributes) click to toggle source
# File lib/rexml/sax2listener.rb, line 31
def start_element uri, localname, qname, attributes
end
start_prefix_mapping(prefix, uri) click to toggle source
# File lib/rexml/sax2listener.rb, line 27
def start_prefix_mapping prefix, uri
end
xmldecl(version, encoding, standalone) click to toggle source

Called when an XML PI is encountered in the document. EG: <?xml version=“1.0” encoding=“utf”?> @p version the version attribute value. EG, “1.0” @p encoding the encoding attribute value, or nil. EG, “utf” @p standalone the standalone attribute value, or nil. EG, nil @p spaced the declaration is followed by a line break

# File lib/rexml/sax2listener.rb, line 88
def xmldecl version, encoding, standalone
end


class REXML::Source - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Source

A Source can be searched for patterns, and wraps buffers and other objects and provides consumption of text

In Files

  • lib/rexml/source.rb

Parent

Object

Included Modules

  • REXML::Encoding

Attributes

buffer[R]

The current buffer (what we're going to read next)

encoding[R]
line[R]

The line number of the last consumed text

Public Class Methods

new(arg, encoding=nil) click to toggle source

Constructor @param arg must be a String, and should be a valid XML document @param encoding if non-null, sets the encoding of the source to this value, overriding all encoding detection

# File lib/rexml/source.rb, line 41
def initialize(arg, encoding=nil)
  @orig = @buffer = arg
  if encoding
    self.encoding = encoding
  else
    detect_encoding
  end
  @line = 0
end

Public Instance Methods

consume( pattern ) click to toggle source
# File lib/rexml/source.rb, line 85
def consume( pattern )
  @buffer = $' if pattern.match( @buffer )
end
current_line() click to toggle source

@return the current line in the source

# File lib/rexml/source.rb, line 115
def current_line
  lines = @orig.split
  res = lines.grep @buffer[0..30]
  res = res[-1] if res.kind_of? Array
  lines.index( res ) if res
end
empty?() click to toggle source

@return true if the Source is exhausted

# File lib/rexml/source.rb, line 106
def empty?
  @buffer == ""
end
encoding=(enc) click to toggle source

Inherited from Encoding Overridden to support optimized en/decoding

# File lib/rexml/source.rb, line 54
def encoding=(enc)
  return unless super
  encoding_updated
end
match(pattern, cons=false) click to toggle source
# File lib/rexml/source.rb, line 99
def match(pattern, cons=false)
  md = pattern.match(@buffer)
  @buffer = $' if cons and md
  return md
end
match_to( char, pattern ) click to toggle source
# File lib/rexml/source.rb, line 89
def match_to( char, pattern )
  return pattern.match(@buffer)
end
match_to_consume( char, pattern ) click to toggle source
# File lib/rexml/source.rb, line 93
def match_to_consume( char, pattern )
  md = pattern.match(@buffer)
  @buffer = $'
  return md
end
position() click to toggle source
# File lib/rexml/source.rb, line 110
def position
  @orig.index( @buffer )
end
read() click to toggle source
# File lib/rexml/source.rb, line 82
def read
end
scan(pattern, cons=false) click to toggle source

Scans the source for a given pattern. Note, that this is not your usual scan() method. For one thing, the pattern argument has some requirements; for another, the source can be consumed. You can easily confuse this method. Originally, the patterns were easier to construct and this method more robust, because this method generated search regexes on the fly; however, this was computationally expensive and slowed down the entire REXML package considerably, since this is by far the most commonly called method. @param pattern must be a Regexp, and must be in the form of /^s*(#{your pattern, with no groups})(.*)/. The first group will be returned; the second group is used if the consume flag is set. @param consume if true, the pattern returned will be consumed, leaving everything after it in the Source. @return the pattern, if found, or nil if the Source is empty or the pattern is not found.

# File lib/rexml/source.rb, line 75
def scan(pattern, cons=false)
  return nil if @buffer.nil?
  rv = @buffer.scan(pattern)
  @buffer = $' if cons and rv.size>0
  rv
end


class REXML::SourceFactory - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::SourceFactory

Generates Source-s. USE THIS CLASS.

In Files

  • lib/rexml/source.rb

Parent

Object

Public Class Methods

create_from(arg) click to toggle source

Generates a Source object @param arg Either a String, or an IO @return a Source, or nil if a bad argument was given

# File lib/rexml/source.rb, line 9
def SourceFactory::create_from(arg)
  if arg.respond_to? :read and
      arg.respond_to? :readline and
      arg.respond_to? :nil? and
      arg.respond_to? :eof?
    IOSource.new(arg)
  elsif arg.respond_to? :to_str
    require 'stringio'
    IOSource.new(StringIO.new(arg))
  elsif arg.kind_of? Source
    arg
  else
    raise "#{arg.class} is not a valid input stream.  It must walk \n"+
      "like either a String, an IO, or a Source."
  end
end


module REXML::StreamListener - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::StreamListener

A template for stream parser listeners. Note that the declarations (attlistdecl, elementdecl, etc) are trivially processed; REXML doesn't yet handle doctype entity declarations, so you have to parse them out yourself.

In Files

  • lib/rexml/streamlistener.rb

Public Instance Methods

attlistdecl(element_name, attributes, raw_content) click to toggle source

If a doctype includes an ATTLIST declaration, it will cause this method to be called. The content is the declaration itself, unparsed. EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as “el attr CDATA #REQUIRED”. This is the same for all of the .*decl methods.

# File lib/rexml/streamlistener.rb, line 50
def attlistdecl element_name, attributes, raw_content
end
cdata(content) click to toggle source

Called when <![CDATA[ … ]]> is encountered in a document. @p content “…”

# File lib/rexml/streamlistener.rb, line 82
def cdata content
end
comment(comment) click to toggle source

Called when a comment is encountered. @p comment The content of the comment

# File lib/rexml/streamlistener.rb, line 32
def comment comment
end
doctype(name, pub_sys, long_name, uri) click to toggle source

Handles a doctype declaration. Any attributes of the doctype which are not supplied will be nil. # EG, <!DOCTYPE me PUBLIC “foo” “bar”> @p name the name of the doctype; EG, “me” @p pub_sys “PUBLIC”, “SYSTEM”, or nil. EG, “PUBLIC” @p long_name the supplied long name, or nil. EG, “foo” @p uri the uri of the doctype, or nil. EG, “bar”

# File lib/rexml/streamlistener.rb, line 40
def doctype name, pub_sys, long_name, uri
end
doctype_end() click to toggle source

Called when the doctype is done

# File lib/rexml/streamlistener.rb, line 43
def doctype_end
end
elementdecl(content) click to toggle source

<!ELEMENT …>

# File lib/rexml/streamlistener.rb, line 53
def elementdecl content
end
entity(content) click to toggle source

Called when %foo; is encountered in a doctype declaration. @p content “foo”

# File lib/rexml/streamlistener.rb, line 78
def entity content
end
entitydecl(content) click to toggle source

<!ENTITY …> The argument passed to this method is an array of the entity declaration. It can be in a number of formats, but in general it returns (example, result):

<!ENTITY % YN '"Yes"'>
["%", "YN", "'\"Yes\"'", "\""]
<!ENTITY % YN 'Yes'>
["%", "YN", "'Yes'", "s"]
<!ENTITY WhatHeSaid "He said %YN;">
["WhatHeSaid", "\"He said %YN;\"", "YN"]
<!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
["open-hatch", "SYSTEM", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
<!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
["open-hatch", "PUBLIC", "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\"", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
<!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif>
["hatch-pic", "SYSTEM", "\"../grafix/OpenHatch.gif\"", "\n\t\t\t\t\t\t\tNDATA gif", "gif"]
# File lib/rexml/streamlistener.rb, line 71
def entitydecl content
end
instruction(name, instruction) click to toggle source

Called when an instruction is encountered. EG: <?xsl sheet='foo'?> @p name the instruction name; in the example, “xsl” @p instruction the rest of the instruction. In the example, “sheet='foo'”

# File lib/rexml/streamlistener.rb, line 28
def instruction name, instruction
end
notationdecl(content) click to toggle source

<!NOTATION …>

# File lib/rexml/streamlistener.rb, line 74
def notationdecl content
end
tag_end(name) click to toggle source

Called when the end tag is reached. In the case of <tag/>, #tag_end will be called immidiately after #tag_start @p the name of the tag

# File lib/rexml/streamlistener.rb, line 18
def tag_end name
end
tag_start(name, attrs) click to toggle source

Called when a tag is encountered. @p name the tag name @p attrs an array of arrays of attribute/value pairs, suitable for use with assoc or rassoc. IE, <tag attr1=“value1” attr2=“value2”> will result in #tag_start( “tag”, # [[“attr1”,“value1”],])

# File lib/rexml/streamlistener.rb, line 13
def tag_start name, attrs
end
text(text) click to toggle source

Called when text is encountered in the document @p text the text content.

# File lib/rexml/streamlistener.rb, line 22
def text text
end
xmldecl(version, encoding, standalone) click to toggle source

Called when an XML PI is encountered in the document. EG: <?xml version=“1.0” encoding=“utf”?> @p version the version attribute value. EG, “1.0” @p encoding the encoding attribute value, or nil. EG, “utf” @p standalone the standalone attribute value, or nil. EG, nil

# File lib/rexml/streamlistener.rb, line 89
def xmldecl version, encoding, standalone
end


class REXML::SyncEnumerator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::SyncEnumerator

In Files

  • lib/rexml/syncenumerator.rb

Parent

Object

Included Modules

  • Enumerable

Public Class Methods

new(*enums) click to toggle source

Creates a new SyncEnumerator which enumerates rows of given Enumerable objects.

# File lib/rexml/syncenumerator.rb, line 7
def initialize(*enums)
  @gens = enums
  @length = @gens.collect {|x| x.size }.max
end

Public Instance Methods

each() { |collect {|x| x}| ... } click to toggle source

Enumerates rows of the Enumerable objects.

# File lib/rexml/syncenumerator.rb, line 25
def each
  @length.times {|i|
    yield @gens.collect {|x| x[i]}
  }
  self
end
length() click to toggle source

Returns the number of enumerated Enumerable objects, i.e. the size of each row.

# File lib/rexml/syncenumerator.rb, line 20
def length
  @gens.length
end
size() click to toggle source

Returns the number of enumerated Enumerable objects, i.e. the size of each row.

# File lib/rexml/syncenumerator.rb, line 14
def size
  @gens.size
end


class REXML::Text - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Text

Represents text nodes in an XML document

In Files

  • lib/rexml/text.rb

Parent

REXML::Child

Included Modules

  • Comparable

Constants

EREFERENCE
NEEDS_A_SECOND_CHECK
NUMERICENTITY
REFERENCE
SETUTITSBUS
SLAICEPS

Characters which are substituted in written strings

SPECIALS

The order in which the substitutions occur

SUBSTITUTES
VALID_CHAR
VALID_XML_CHARS

Attributes

raw[RW]

If raw is true, then REXML leaves the value alone

Public Class Methods

check(string, pattern, doctype) click to toggle source

check for illegal characters

# File lib/rexml/text.rb, line 129
def Text.check string, pattern, doctype

  # illegal anywhere
  if string !~ VALID_XML_CHARS
    if String.method_defined? :encode
      string.chars.each do |c|
        case c.ord
        when *VALID_CHAR
        else
          raise "Illegal character #{c.inspect} in raw string \"#{string}\""
        end
      end
    else
      string.scan(/[\x00-\x7F]|[\x80-\xBF][\xC0-\xF0]*|[\xC0-\xF0]/) do |c|
        case c.unpack('U')
        when *VALID_CHAR
        else
          raise "Illegal character #{c.inspect} in raw string \"#{string}\""
        end
      end
    end
  end

  # context sensitive
  string.scan(pattern) do
    if $1[-1] != ;
      raise "Illegal character '#{$1}' in raw string \"#{string}\""
    elsif $1[0] == &
      if $5 and $5[0] == #
        case ($5[1] == x ? $5[2..-1].to_i(16) : $5[1..-1].to_i)
        when *VALID_CHAR
        else
          raise "Illegal character '#{$1}' in raw string \"#{string}\""
        end
      # FIXME: below can't work but this needs API change.
      # elsif @parent and $3 and !SUBSTITUTES.include?($1)
      #   if !doctype or !doctype.entities.has_key?($3)
      #     raise "Undeclared entity '#{$1}' in raw string \"#{string}\""
      #   end
      end
    end
  end
end
expand(ref, doctype, filter) click to toggle source
# File lib/rexml/text.rb, line 396
def Text.expand(ref, doctype, filter)
  if ref[1] == #
    if ref[2] == x
      [ref[3...-1].to_i(16)].pack('U*')
    else
      [ref[2...-1].to_i].pack('U*')
    end
  elsif ref == '&amp;'
    '&'
  elsif filter and filter.include?( ref[1...-1] )
    ref
  elsif doctype
    doctype.entity( ref[1...-1] ) or ref
  else
    entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ]
    entity_value ? entity_value.value : ref
  end
end
new(arg, respect_whitespace=false, parent=nil, raw=nil, entity_filter=nil, illegal=NEEDS_A_SECOND_CHECK ) click to toggle source

Constructor arg if a String, the content is set to the String. If a Text, the object is shallowly cloned.

respect_whitespace (boolean, false) if true, whitespace is respected

parent (nil) if this is a Parent object, the parent will be set to this.

raw (nil) This argument can be given three values. If true, then the value of used to construct this object is expected to contain no unescaped XML markup, and REXML will not change the text. If this value is false, the string may contain any characters, and REXML will escape any and all defined entities whose values are contained in the text. If this value is nil (the default), then the raw value of the parent will be used as the raw value for this node. If there is no raw value for the parent, and no value is supplied, the default is false. Use this field if you have entities defined for some text, and you don't want REXML to escape that text in output.

Text.new( "<&", false, nil, false ) #-> "&lt;&amp;"
Text.new( "&lt;&amp;", false, nil, false ) #-> "&amp;lt;&amp;amp;"
Text.new( "<&", false, nil, true )  #-> Parse exception
Text.new( "&lt;&amp;", false, nil, true )  #-> "&lt;&amp;"
# Assume that the entity "s" is defined to be "sean"
# and that the entity    "r" is defined to be "russell"
Text.new( "sean russell" )          #-> "&s; &r;"
Text.new( "sean russell", false, nil, true ) #-> "sean russell"

entity_filter (nil) This can be an array of entities to match in the supplied text. This argument is only useful if raw is set to false.

Text.new( "sean russell", false, nil, false, ["s"] ) #-> "&s; russell"
Text.new( "sean russell", false, nil, true, ["s"] ) #-> "sean russell"

In the last example, the entity_filter argument is ignored.

illegal INTERNAL USE ONLY

# File lib/rexml/text.rb, line 93
def initialize(arg, respect_whitespace=false, parent=nil, raw=nil,
  entity_filter=nil, illegal=NEEDS_A_SECOND_CHECK )

  @raw = false
  @parent = nil

  if parent
    super( parent )
    @raw = parent.raw
  end

  @raw = raw unless raw.nil?
  @entity_filter = entity_filter
  @normalized = @unnormalized = nil

  if arg.kind_of? String
    @string = arg.dup
    @string.squeeze!(" \n\t") unless respect_whitespace
  elsif arg.kind_of? Text
    @string = arg.to_s
    @raw = arg.raw
  elsif
    raise "Illegal argument of type #{arg.type} for Text constructor (#{arg})"
  end

  @string.gsub!( /\r\n?/, "\n" )

  Text.check(@string, illegal, doctype) if @raw
end
normalize( input, doctype=nil, entity_filter=nil ) click to toggle source

Escapes all possible entities

# File lib/rexml/text.rb, line 361
def Text::normalize( input, doctype=nil, entity_filter=nil )
  copy = input.to_s
  # Doing it like this rather than in a loop improves the speed
  #copy = copy.gsub( EREFERENCE, '&amp;' )
  copy = copy.gsub( "&", "&amp;" )
  if doctype
    # Replace all ampersands that aren't part of an entity
    doctype.entities.each_value do |entity|
      copy = copy.gsub( entity.value,
        "&#{entity.name};" ) if entity.value and
          not( entity_filter and entity_filter.include?(entity) )
    end
  else
    # Replace all ampersands that aren't part of an entity
    DocType::DEFAULT_ENTITIES.each_value do |entity|
      copy = copy.gsub(entity.value, "&#{entity.name};" )
    end
  end
  copy
end
read_with_substitution( input, illegal=nil ) click to toggle source

Reads text, substituting entities

# File lib/rexml/text.rb, line 335
def Text::read_with_substitution( input, illegal=nil )
  copy = input.clone

  if copy =~ illegal
    raise ParseException.new( "malformed text: Illegal character #$& in \"#{copy}\"" )
  end if illegal

  copy.gsub!( /\r\n?/, "\n" )
  if copy.include? &
    copy.gsub!( SETUTITSBUS[0], SLAICEPS[0] )
    copy.gsub!( SETUTITSBUS[1], SLAICEPS[1] )
    copy.gsub!( SETUTITSBUS[2], SLAICEPS[2] )
    copy.gsub!( SETUTITSBUS[3], SLAICEPS[3] )
    copy.gsub!( SETUTITSBUS[4], SLAICEPS[4] )
    copy.gsub!( /&#0*((?:\d+)|(?:x[a-f0-9]+));/ ) {
      m=$1
      #m='0' if m==''
      m = "0#{m}" if m[0] == x
      [Integer(m)].pack('U*')
    }
  end
  copy
end
unnormalize( string, doctype=nil, filter=nil, illegal=nil ) click to toggle source

Unescapes all possible entities

# File lib/rexml/text.rb, line 383
def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
  sum = 0
  string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) {
    s = Text.expand($&, doctype, filter)
    if sum + s.bytesize > REXML.entity_expansion_text_limit
      raise "entity expansion has grown too large"
    else
      sum += s.bytesize
    end
    s
  }
end

Public Instance Methods

<<( to_append ) click to toggle source

Appends text to this text node. The text is appended in the raw mode of this text node.

# File lib/rexml/text.rb, line 189
def <<( to_append )
  @string << to_append.gsub( /\r\n?/, "\n" )
end
<=>( other ) click to toggle source

other a String or a Text returns the result of (#to_s <=> arg.to_s)

# File lib/rexml/text.rb, line 196
def <=>( other )
  to_s() <=> other.to_s
end
clone() click to toggle source
# File lib/rexml/text.rb, line 182
def clone
  return Text.new(self)
end
doctype() click to toggle source
# File lib/rexml/text.rb, line 200
def doctype
  if @parent
    doc = @parent.document
    doc.doctype if doc
  end
end
empty?() click to toggle source
# File lib/rexml/text.rb, line 177
def empty?
  @string.size==0
end
indent_text(string, level=1, style="\t", indentfirstline=true) click to toggle source
# File lib/rexml/text.rb, line 275
def indent_text(string, level=1, style="\t", indentfirstline=true)
  return string if level < 0
  new_string = ''
  string.each_line { |line|
    indent_string = style * level
    new_line = (indent_string + line).sub(/[\s]+$/,'')
    new_string << new_line
  }
  new_string.strip! unless indentfirstline
  return new_string
end
inspect() click to toggle source
# File lib/rexml/text.rb, line 228
def inspect
  @string.inspect
end
node_type() click to toggle source
# File lib/rexml/text.rb, line 173
def node_type
  :text
end
parent=(parent) click to toggle source
# File lib/rexml/text.rb, line 123
def parent= parent
  super(parent)
  Text.check(@string, NEEDS_A_SECOND_CHECK, doctype) if @raw and @parent
end
to_s() click to toggle source

Returns the string value of this text node. This string is always escaped, meaning that it is a valid XML text node string, and all entities that can be escaped, have been inserted. This method respects the entity filter set in the constructor.

# Assume that the entity "s" is defined to be "sean", and that the
# entity "r" is defined to be "russell"
t = Text.new( "< & sean russell", false, nil, false, ['s'] )
t.to_s   #-> "&lt; &amp; &s; russell"
t = Text.new( "< & &s; russell", false, nil, false )
t.to_s   #-> "&lt; &amp; &s; russell"
u = Text.new( "sean russell", false, nil, true )
u.to_s   #-> "sean russell"
# File lib/rexml/text.rb, line 221
def to_s
  return @string if @raw
  return @normalized if @normalized

  @normalized = Text::normalize( @string, doctype, @entity_filter )
end
value() click to toggle source

Returns the string value of this text. This is the text without entities, as it might be used programmatically, or printed to the console. This ignores the 'raw' attribute setting, and any entity_filter.

# Assume that the entity "s" is defined to be "sean", and that the
# entity "r" is defined to be "russell"
t = Text.new( "< & sean russell", false, nil, false, ['s'] )
t.value   #-> "< & sean russell"
t = Text.new( "< & &s; russell", false, nil, false )
t.value   #-> "< & sean russell"
u = Text.new( "sean russell", false, nil, true )
u.value   #-> "sean russell"
# File lib/rexml/text.rb, line 245
def value
  return @unnormalized if @unnormalized
  @unnormalized = Text::unnormalize( @string, doctype )
end
value=( val ) click to toggle source

Sets the contents of this text node. This expects the text to be unnormalized. It returns self.

e = Element.new( "a" )
e.add_text( "foo" )   # <a>foo</a>
e[0].value = "bar"    # <a>bar</a>
e[0].value = "<a>"    # <a>&lt;a&gt;</a>
# File lib/rexml/text.rb, line 257
def value=( val )
  @string = val.gsub( /\r\n?/, "\n" )
  @unnormalized = nil
  @normalized = nil
  @raw = false
end
wrap(string, width, addnewline=false) click to toggle source
# File lib/rexml/text.rb, line 264
def wrap(string, width, addnewline=false)
  # Recursively wrap string at width.
  return string if string.length <= width
  place = string.rindex(' ', width) # Position in string with last ' ' before cutoff
  if addnewline then
    return "\n" + string[0,place] + "\n" + wrap(string[place+1..-1], width)
  else
    return string[0,place] + "\n" + wrap(string[place+1..-1], width)
  end
end
write( writer, indent=-1, transitive=false, ie_hack=false ) click to toggle source

DEPRECATED

See REXML::Formatters

# File lib/rexml/text.rb, line 290
def write( writer, indent=-1, transitive=false, ie_hack=false )
  Kernel.warn("#{self.class.name}.write is deprecated.  See REXML::Formatters")
  formatter = if indent > -1
      REXML::Formatters::Pretty.new( indent )
    else
      REXML::Formatters::Default.new
    end
  formatter.write( self, writer )
end
write_with_substitution(out, input) click to toggle source

Writes out text, substituting special characters beforehand. out A String, IO, or any other object supporting <<( String ) input the text to substitute and the write out

z=utf8.unpack("U*")
ascOut=""
z.each{|r|
  if r <  0x100
    ascOut.concat(r.chr)
  else
    ascOut.concat(sprintf("&#x%x;", r))
  end
}
puts ascOut

# File lib/rexml/text.rb, line 322
def write_with_substitution out, input
  copy = input.clone
  # Doing it like this rather than in a loop improves the speed
  copy.gsub!( SPECIALS[0], SUBSTITUTES[0] )
  copy.gsub!( SPECIALS[1], SUBSTITUTES[1] )
  copy.gsub!( SPECIALS[2], SUBSTITUTES[2] )
  copy.gsub!( SPECIALS[3], SUBSTITUTES[3] )
  copy.gsub!( SPECIALS[4], SUBSTITUTES[4] )
  copy.gsub!( SPECIALS[5], SUBSTITUTES[5] )
  out << copy
end
xpath() click to toggle source

FIXME This probably won't work properly

# File lib/rexml/text.rb, line 302
def xpath
  path = @parent.xpath
  path += "/text()"
  return path
end


class REXML::UndefinedNamespaceException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::UndefinedNamespaceException

In Files

  • lib/rexml/undefinednamespaceexception.rb

Parent

REXML::ParseException

Public Class Methods

new( prefix, source, parser ) click to toggle source
# File lib/rexml/undefinednamespaceexception.rb, line 4
def initialize( prefix, source, parser )
  super( "Undefined prefix #{prefix} found" )
end


module REXML::Validation - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::Validation

In Files

  • lib/rexml/validation/relaxng.rb
  • lib/rexml/validation/validation.rb
  • lib/rexml/validation/validationexception.rb


class REXML::Validation::Choice - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Validation::Choice

In Files

  • lib/rexml/validation/relaxng.rb

Parent

REXML::Validation::State

Public Class Methods

new(context) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 363
def initialize context
  super
  @choices = []
end

Public Instance Methods

<<( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 374
def <<( event )
  add_event_to_arry( @choices, event )
end
expected() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 411
def expected
  #puts "IN CHOICE EXPECTED"
  #puts "EVENTS = #{@events.inspect}"
  return [@events[@current]] if @events.size > 0
  return @choices.collect do |x|
    if x[0].kind_of? State
      x[0].expected
    else
      x[0]
    end
  end.flatten
end
inspect() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 424
def inspect
  "< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' or ')} >"
end
matches?( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 406
def matches?( event )
  return @events[@current].matches?( event ) if @events.size > 0
  !@choices.find{|evt| evt[0].matches?(event)}.nil?
end
next( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 378
def next( event )
  # Make the choice if we haven't
  if @events.size == 0
    c = 0 ; max = @choices.size
    while c < max
      if @choices[c][0].class == Ref
        expand_ref_in( @choices[c], 0 )
        @choices += @choices[c]
        @choices.delete( @choices[c] )
        max -= 1
      else
        c += 1
      end
    end
    @events = @choices.find { |evt| evt[0].matches? event }
    # Remove the references
    # Find the events
  end
  #puts "In next with #{event.inspect}."
  #puts "events is #{@events.inspect}"
  unless @events
    @events = []
    return nil
  end
  #puts "current = #@current"
  super
end
reset() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 368
def reset
  super
  @events = []
  @choices.each { |c| c.each { |s| s.reset if s.kind_of? State } }
end

Protected Instance Methods

add_event_to_arry( arry, evt ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 429
def add_event_to_arry( arry, evt )
  if evt.kind_of? State or evt.class == Ref
    arry << [evt]
  elsif evt[0] == :text
   if arry[-1] and
      arry[-1][-1].kind_of?( Event ) and
      arry[-1][-1].event_type == :text and @value

      arry[-1][-1].event_arg = evt[1]
      @value = false
   end
  else
    arry << [] if evt[0] == :start_element
    arry[-1] << generate_event( evt )
  end
end


class REXML::Validation::Event - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Validation::Event

In Files

  • lib/rexml/validation/validation.rb

Parent

Object

Attributes

event_arg[RW]
event_type[R]

Public Class Methods

new(event_type, event_arg=nil ) click to toggle source
# File lib/rexml/validation/validation.rb, line 80
def initialize(event_type, event_arg=nil )
  @event_type = event_type
  @event_arg = event_arg
end

Public Instance Methods

==( other ) click to toggle source
# File lib/rexml/validation/validation.rb, line 141
def ==( other )
  return false unless other.kind_of? Event
  @event_type == other.event_type and @event_arg == other.event_arg
end
done?() click to toggle source
# File lib/rexml/validation/validation.rb, line 88
def done?
  @done
end
inspect() click to toggle source
# File lib/rexml/validation/validation.rb, line 150
def inspect
  "#{@event_type.inspect}( #@event_arg )"
end
matches?( event ) click to toggle source
# File lib/rexml/validation/validation.rb, line 96
      def matches?( event )
        #puts "#@event_type =? #{event[0]} && #@event_arg =? #{event[1]} "
        return false unless event[0] == @event_type
        case event[0]
        when nil
          return true
        when :start_element
          return true if event[1] == @event_arg
        when :end_element
          return true
        when :start_attribute
          return true if event[1] == @event_arg
        when :end_attribute
          return true
        when :end_document
          return true
        when :text
          return (@event_arg.nil? or @event_arg == event[1])
        when :processing_instruction
          false
        when :xmldecl
          false
        when :start_doctype
          false
        when :end_doctype
          false
        when :externalentity
          false
        when :elementdecl
          false
        when :entity
          false
        when :attlistdecl
          false
        when :notationdecl
          false
        when :end_doctype
          false
        else
          false
        end
      end
single?() click to toggle source
# File lib/rexml/validation/validation.rb, line 92
def single?
  return (@event_type != :start_element and @event_type != :start_attribute)
end
to_s() click to toggle source
# File lib/rexml/validation/validation.rb, line 146
def to_s
  inspect
end


class REXML::Validation::Interleave - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Validation::Interleave

In Files

  • lib/rexml/validation/relaxng.rb

Parent

REXML::Validation::Choice

Public Class Methods

new(context) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 449
def initialize context
  super
  @choice = 0
end

Public Instance Methods

expected() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 529
def expected
  #puts "IN CHOICE EXPECTED"
  #puts "EVENTS = #{@events.inspect}"
  return [@events[@current]] if @events[@current]
  return @choices[@choice..-1].collect do |x|
    if x[0].kind_of? State
      x[0].expected
    else
      x[0]
    end
  end.flatten
end
inspect() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 542
def inspect
  "< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' and ')} >"
end
matches?( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 524
def matches?( event )
  return @events[@current].matches?( event ) if @events[@current]
  !@choices[@choice..-1].find{|evt| evt[0].matches?(event)}.nil?
end
next( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 488
def next( event )
  # Find the next series
  next_current(event) unless @events[@current]
  return nil unless @events[@current]

  expand_ref_in( @events, @current ) if @events[@current].class == Ref
 #puts "In next with #{event.inspect}."
 #puts "Next (#@current) is #{@events[@current]}"
  if ( @events[@current].kind_of? State )
    @current += 1
    @events[@current-1].previous = self
    return @events[@current-1].next( event )
  end
 #puts "Current isn't a state"
  return @previous.pop.next( event ) if @events[@current].nil?
  if ( @events[@current].matches?(event) )
    @current += 1
    if @events[@current].nil?
     #puts "#{inspect[0,5]} 1RETURNING self" unless @choices[@choice].nil?
      return self unless @choices[@choice].nil?
     #puts "#{inspect[0,5]} 1RETURNING #{@previous[-1].inspect[0,5]}"
      return @previous.pop
    elsif @events[@current].kind_of? State
      @current += 1
     #puts "#{inspect[0,5]} 2RETURNING (#{@current-1}) #{@events[@current-1].inspect[0,5]}; on return, next is #{@events[@current]}"
      @events[@current-1].previous = self
      return @events[@current-1]
    else
     #puts "#{inspect[0,5]} RETURNING self w/ next(#@current) = #{@events[@current]}"
      return self
    end
  else
    return nil
  end
end
next_current( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 458
def next_current( event )
  # Expand references
  c = 0 ; max = @choices.size
  while c < max
    if @choices[c][0].class == Ref
      expand_ref_in( @choices[c], 0 )
      @choices += @choices[c]
      @choices.delete( @choices[c] )
      max -= 1
    else
      c += 1
    end
  end
  @events = @choices[@choice..-1].find { |evt| evt[0].matches? event }
  @current = 0
  if @events
    # reorder the choices
    old = @choices[@choice]
    idx = @choices.index( @events )
    @choices[@choice] = @events
    @choices[idx] = old
    @choice += 1
  end

 #puts "In next with #{event.inspect}."
 #puts "events is #{@events.inspect}"
  @events = [] unless @events
end
reset() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 454
def reset
  @choice = 0
end


class REXML::Validation::OneOrMore - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Validation::OneOrMore

In Files

  • lib/rexml/validation/relaxng.rb

Parent

REXML::Validation::State

Public Class Methods

new(context) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 316
def initialize context
  super
  @ord = 0
end

Public Instance Methods

expected() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 352
def expected
  if @current == 0 and @ord > 0
    return [@previous[-1].expected, @events[0]].flatten
  else
    return [@events[@current]]
  end
end
matches?( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 347
def matches?( event )
  @events[@current].matches?(event) ||
  (@current == 0 and @ord > 0 and @previous[-1].matches?(event))
end
next( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 326
def next( event )
  expand_ref_in( @events, @current ) if @events[@current].class == Ref
  if ( @events[@current].matches?(event) )
    @current += 1
    @ord += 1
    if @events[@current].nil?
      @current = 0
      return self
    elsif @events[@current].kind_of? State
      @current += 1
      @events[@current-1].previous = self
      return @events[@current-1]
    else
      return self
    end
  else
    return @previous.pop.next( event ) if @current == 0 and @ord > 0
    return nil
  end
end
reset() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 321
def reset
  super
  @ord = 0
end


class REXML::Validation::Optional - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Validation::Optional

In Files

  • lib/rexml/validation/relaxng.rb

Parent

REXML::Validation::State

Public Instance Methods

expected() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 279
def expected
  return [ @prior.expected, @events[0] ].flatten if @current == 0
  return [@events[@current]]
end
matches?(event) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 274
def matches?(event)
  @events[@current].matches?(event) ||
  (@current == 0 and @previous[-1].matches?(event))
end
next( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 264
def next( event )
  if @current == 0
    rv = super
    return rv if rv
    @prior = @previous.pop
    return @prior.next( event )
  end
  super
end


class REXML::Validation::Ref - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Validation::Ref

In Files

  • lib/rexml/validation/relaxng.rb

Parent

Object

Public Class Methods

new(value) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 548
def initialize value
  @value = value
end

Public Instance Methods

inspect() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 554
def inspect
  "{#{to_s}}"
end
to_s() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 551
def to_s
  @value
end


class REXML::Validation::RelaxNG - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Validation::RelaxNG

Implemented:

  • empty

  • element

  • attribute

  • text

  • optional

  • choice

  • oneOrMore

  • zeroOrMore

  • group

  • value

  • interleave

  • mixed

  • ref

  • grammar

  • start

  • define

Not implemented:

  • data

  • param

  • include

  • externalRef

  • notAllowed

  • anyName

  • nsName

  • except

  • name

In Files

  • lib/rexml/validation/relaxng.rb

Parent

Object

Included Modules

  • REXML::Validation::Validator

Constants

EMPTY
INFINITY
TEXT

Attributes

count[RW]
current[RW]
references[R]

Public Class Methods

new(source) click to toggle source

FIXME: Namespaces

# File lib/rexml/validation/relaxng.rb, line 45
def initialize source
  parser = REXML::Parsers::BaseParser.new( source )

  @count = 0
  @references = {}
  @root = @current = Sequence.new(self)
  @root.previous = true
  states = [ @current ]
  begin
    event = parser.pull
    case event[0]
    when :start_element
      case event[1]
      when "empty"
      when "element", "attribute", "text", "value"
        states[-1] << event
      when "optional"
        states << Optional.new( self )
        states[-2] << states[-1]
      when "choice"
        states << Choice.new( self )
        states[-2] << states[-1]
      when "oneOrMore"
        states << OneOrMore.new( self )
        states[-2] << states[-1]
      when "zeroOrMore"
        states << ZeroOrMore.new( self )
        states[-2] << states[-1]
      when "group"
        states << Sequence.new( self )
        states[-2] << states[-1]
      when "interleave"
        states << Interleave.new( self )
        states[-2] << states[-1]
      when "mixed"
        states << Interleave.new( self )
        states[-2] << states[-1]
        states[-1] << TEXT
      when "define"
        states << [ event[2]["name"] ]
      when "ref"
        states[-1] << Ref.new( event[2]["name"] )
      when "anyName"
        states << AnyName.new( self )
        states[-2] << states[-1]
      when "nsName"
      when "except"
      when "name"
      when "data"
      when "param"
      when "include"
      when "grammar"
      when "start"
      when "externalRef"
      when "notAllowed"
      end
    when :end_element
      case event[1]
      when "element", "attribute"
        states[-1] << event
      when "zeroOrMore", "oneOrMore", "choice", "optional",
        "interleave", "group", "mixed"
        states.pop
      when "define"
        ref = states.pop
        @references[ ref.shift ] = ref
      #when "empty"
      end
    when :end_document
      states[-1] << event
    when :text
      states[-1] << event
    end
  end while event[0] != :end_document
end

Public Instance Methods

receive(event) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 121
def receive event
  validate( event )
end


class REXML::Validation::Sequence - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Validation::Sequence

In Files

  • lib/rexml/validation/relaxng.rb

Parent

REXML::Validation::State

Public Instance Methods

matches?(event) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 257
def matches?(event)
  @events[@current].matches?( event )
end


class REXML::Validation::State - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Validation::State

In Files

  • lib/rexml/validation/relaxng.rb

Parent

Object

Public Class Methods

new( context ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 127
def initialize( context )
  @previous = []
  @events = []
  @current = 0
  @count = context.count += 1
  @references = context.references
  @value = false
end

Public Instance Methods

<<( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 196
def <<( event )
  add_event_to_arry( @events, event )
end
expected() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 192
def expected
  return [@events[@current]]
end
inspect() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 185
def inspect
  "< #{to_s} #{@events.collect{|e|
    pre = e == @events[@current] ? '#' : ''
    pre + e.inspect unless self == e
  }.join(', ')} >"
end
next( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 146
def next( event )
  #print "In next with #{event.inspect}.  "
  #puts "Next (#@current) is #{@events[@current]}"
  #p @previous
  return @previous.pop.next( event ) if @events[@current].nil?
  expand_ref_in( @events, @current ) if @events[@current].class == Ref
  if ( @events[@current].kind_of? State )
    @current += 1
    @events[@current-1].previous = self
    return @events[@current-1].next( event )
  end
  #puts "Current isn't a state"
  if ( @events[@current].matches?(event) )
    @current += 1
    if @events[@current].nil?
      #puts "#{inspect[0,5]} 1RETURNING #{@previous.inspect[0,5]}"
      return @previous.pop
    elsif @events[@current].kind_of? State
      @current += 1
      #puts "#{inspect[0,5]} 2RETURNING (#{@current-1}) #{@events[@current-1].inspect[0,5]}; on return, next is #{@events[@current]}"
      @events[@current-1].previous = self
      return @events[@current-1]
    else
      #puts "#{inspect[0,5]} RETURNING self w/ next(#@current) = #{@events[@current]}"
      return self
    end
  else
    return nil
  end
end
previous=( previous ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 142
def previous=( previous )
  @previous << previous
end
reset() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 136
def reset
  return if @current == 0
  @current = 0
  @events.each {|s| s.reset if s.kind_of? State }
end
to_s() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 177
def to_s
  # Abbreviated:
  self.class.name =~ /(?:::)(\w)\w+$/
  # Full:
  #self.class.name =~ /(?:::)(\w+)$/
  "#$1.#@count"
end

Protected Instance Methods

add_event_to_arry( arry, evt ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 210
def add_event_to_arry( arry, evt )
  evt = generate_event( evt )
  if evt.kind_of? String
    arry[-1].event_arg = evt if arry[-1].kind_of? Event and @value
    @value = false
  else
    arry << evt
  end
end
expand_ref_in( arry, ind ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 202
def expand_ref_in( arry, ind )
  new_events = []
  @references[ arry[ind].to_s ].each{ |evt|
    add_event_to_arry(new_events,evt)
  }
  arry[ind,1] = new_events
end
generate_event( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 220
def generate_event( event )
  return event if event.kind_of? State or event.class == Ref
  evt = nil
  arg = nil
  case event[0]
  when :start_element
    case event[1]
    when "element"
      evt = :start_element
      arg = event[2]["name"]
    when "attribute"
      evt = :start_attribute
      arg = event[2]["name"]
    when "text"
      evt = :text
    when "value"
      evt = :text
      @value = true
    end
  when :text
    return event[1]
  when :end_document
    return Event.new( event[0] )
  else # then :end_element
    case event[1]
    when "element"
      evt = :end_element
    when "attribute"
      evt = :end_attribute
    end
  end
  return Event.new( evt, arg )
end


class REXML::Validation::ValidationException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Validation::ValidationException

In Files

  • lib/rexml/validation/validationexception.rb

Parent

RuntimeError

Public Class Methods

new(msg) click to toggle source
# File lib/rexml/validation/validationexception.rb, line 4
def initialize msg
  super
end


module REXML::Validation::Validator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::Validation::Validator

In Files

  • lib/rexml/validation/validation.rb

Constants

NILEVENT

Public Instance Methods

dump() click to toggle source
# File lib/rexml/validation/validation.rb, line 14
def dump
  puts @root.inspect
end
reset() click to toggle source
# File lib/rexml/validation/validation.rb, line 7
def reset
  @current = @root
  @root.reset
  @root.previous = true
  @attr_stack = []
  self
end
validate( event ) click to toggle source
# File lib/rexml/validation/validation.rb, line 17
def validate( event )
  #puts "Current: #@current"
  #puts "Event: #{event.inspect}"
  @attr_stack = [] unless defined? @attr_stack
  match = @current.next(event)
  raise ValidationException.new( "Validation error.  Expected: "+
    @current.expected.join( " or " )+" from #{@current.inspect} "+
    " but got #{Event.new( event[0], event[1] ).inspect}" ) unless match
  @current = match

  # Check for attributes
  case event[0]
  when :start_element
    #puts "Checking attributes"
    @attr_stack << event[2]
    begin
      sattr = [:start_attribute, nil]
      eattr = [:end_attribute]
      text = [:text, nil]
      k, = event[2].find { |key,value|
        sattr[1] = key
        #puts "Looking for #{sattr.inspect}"
        m = @current.next( sattr )
        #puts "Got #{m.inspect}"
        if m
          # If the state has text children...
          #puts "Looking for #{eattr.inspect}"
          #puts "Expect #{m.expected}"
          if m.matches?( eattr )
            #puts "Got end"
            @current = m
          else
            #puts "Didn't get end"
            text[1] = value
            #puts "Looking for #{text.inspect}"
            m = m.next( text )
            #puts "Got #{m.inspect}"
            text[1] = nil
            return false unless m
            @current = m if m
          end
          m = @current.next( eattr )
          if m
            @current = m
            true
          else
            false
          end
        else
          false
        end
      }
      event[2].delete(k) if k
    end while k
  when :end_element
    attrs = @attr_stack.pop
    raise ValidationException.new( "Validation error.  Illegal "+
      " attributes: #{attrs.inspect}") if attrs.length > 0
  end
end


class REXML::Validation::ZeroOrMore - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::Validation::ZeroOrMore

In Files

  • lib/rexml/validation/relaxng.rb

Parent

REXML::Validation::Optional

Public Instance Methods

expected() click to toggle source
# File lib/rexml/validation/relaxng.rb, line 308
def expected
  return [ @prior.expected, @events[0] ].flatten if @current == 0
  return [@events[@current]]
end
next( event ) click to toggle source
# File lib/rexml/validation/relaxng.rb, line 287
def next( event )
  expand_ref_in( @events, @current ) if @events[@current].class == Ref
  if ( @events[@current].matches?(event) )
    @current += 1
    if @events[@current].nil?
      @current = 0
      return self
    elsif @events[@current].kind_of? State
      @current += 1
      @events[@current-1].previous = self
      return @events[@current-1]
    else
      return self
    end
  else
    @prior = @previous.pop
    return @prior.next( event ) if @current == 0
    return nil
  end
end


class REXML::XMLDecl - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::XMLDecl

NEEDS DOCUMENTATION

In Files

  • lib/rexml/xmldecl.rb

Parent

REXML::Child

Included Modules

  • REXML::Encoding

Constants

DEFAULT_ENCODING
DEFAULT_STANDALONE
DEFAULT_VERSION
START
STOP

Attributes

stand_alone?[RW]
standalone[RW]
version[RW]
writeencoding[R]
writethis[R]

Public Class Methods

default() click to toggle source

Only use this if you do not want the XML declaration to be written; this object is ignored by the XML writer. Otherwise, instantiate your own XMLDecl and add it to the document.

Note that XML 1.1 documents must include an XML declaration

# File lib/rexml/xmldecl.rb, line 89
def XMLDecl.default
  rv = XMLDecl.new( "1.0" )
  rv.nowrite
  rv
end
new(version=DEFAULT_VERSION, encoding=nil, standalone=nil) click to toggle source
# File lib/rexml/xmldecl.rb, line 18
def initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil)
  @writethis = true
  @writeencoding = !encoding.nil?
  if version.kind_of? XMLDecl
    super()
    @version = version.version
    self.encoding = version.encoding
    @writeencoding = version.writeencoding
    @standalone = version.standalone
  else
    super()
    @version = version
    self.encoding = encoding
    @standalone = standalone
  end
  @version = DEFAULT_VERSION if @version.nil?
end

Public Instance Methods

==( other ) click to toggle source
# File lib/rexml/xmldecl.rb, line 53
def ==( other )
  other.kind_of?(XMLDecl) and
  other.version == @version and
  other.encoding == self.encoding and
  other.standalone == @standalone
end
clone() click to toggle source
# File lib/rexml/xmldecl.rb, line 36
def clone
  XMLDecl.new(self)
end
dowrite() click to toggle source
# File lib/rexml/xmldecl.rb, line 99
def dowrite
  @writethis = true
end
encoding=( enc ) click to toggle source
# File lib/rexml/xmldecl.rb, line 73
def encoding=( enc )
  if enc.nil?
    self.old_enc = "UTF-8"
    @writeencoding = false
  else
    self.old_enc = enc
    @writeencoding = true
  end
  self.dowrite
end
Also aliased as: old_enc=
inspect() click to toggle source
# File lib/rexml/xmldecl.rb, line 103
def inspect
  START.sub(/\/, '') + " ... " + STOP.sub(/\/, '')
end
node_type() click to toggle source
# File lib/rexml/xmldecl.rb, line 66
def node_type
  :xmldecl
end
nowrite() click to toggle source
# File lib/rexml/xmldecl.rb, line 95
def nowrite
  @writethis = false
end
old_enc=( enc ) click to toggle source
Alias for: encoding=
write(writer, indent=-1, transitive=false, ie_hack=false) click to toggle source
indent

Ignored. There must be no whitespace before an XML declaration

transitive

Ignored

ie_hack

Ignored

# File lib/rexml/xmldecl.rb, line 46
def write(writer, indent=-1, transitive=false, ie_hack=false)
  return nil unless @writethis or writer.kind_of? Output
  writer << START.sub(/\/, '')
  writer << " #{content encoding}"
  writer << STOP.sub(/\/, '')
end
xmldecl(version, encoding, standalone) click to toggle source
# File lib/rexml/xmldecl.rb, line 60
def xmldecl version, encoding, standalone
  @version = version
  self.encoding = encoding
  @standalone = standalone
end


module REXML::XMLTokens - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module REXML::XMLTokens

Defines a number of tokens used for parsing XML. Not for general consumption.

In Files

  • lib/rexml/xmltokens.rb

Constants

NAME
NAMECHAR
NAME_STR
NCNAME_STR
NMTOKEN
NMTOKENS
REFERENCE


class REXML::XPath - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::XPath

Wrapper class. Use this class to access the XPath functions.

In Files

  • lib/rexml/xpath.rb

Parent

Object

Included Modules

  • REXML::Functions

Constants

EMPTY_HASH

A base Hash object, supposing to be used when initializing a default empty namespaces set, but is currently unused. TODO: either set the namespaces=EMPTY_HASH, or deprecate this.

Public Class Methods

each(element, path=nil, namespaces=nil, variables={}) click to toggle source

Iterates over nodes that match the given path, calling the supplied block with the match.

element

The context element

path

The xpath to search for. If not supplied or nil, defaults to '*'

namespaces

If supplied, a Hash which defines a namespace mapping

variables

If supplied, a Hash which maps $variables in the query to values. This can be used to avoid XPath injection attacks or to automatically handle escaping string values.

XPath.each( node ) { |el| ... }
XPath.each( node, '/*[@attr='v']' ) { |el| ... }
XPath.each( node, 'ancestor::x' ) { |el| ... }
XPath.each( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"})    {|el| ... }

# File lib/rexml/xpath.rb, line 59
def XPath::each element, path=nil, namespaces=nil, variables={}, &block
  raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
  raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
  parser = XPathParser.new
  parser.namespaces = namespaces
  parser.variables = variables
  path = "*" unless path
  element = [element] unless element.kind_of? Array
  parser.parse(path, element).each( &block )
end
first(element, path=nil, namespaces=nil, variables={}) click to toggle source

Finds and returns the first node that matches the supplied xpath.

element

The context element

path

The xpath to search for. If not supplied or nil, returns the first node matching '*'.

namespaces

If supplied, a Hash which defines a namespace mapping.

variables

If supplied, a Hash which maps $variables in the query to values. This can be used to avoid XPath injection attacks or to automatically handle escaping string values.

XPath.first( node )
XPath.first( doc, "//b"} )
XPath.first( node, "a/x:b", { "x"=>"http://doofus" } )
XPath.first( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"})

# File lib/rexml/xpath.rb, line 30
def XPath::first element, path=nil, namespaces=nil, variables={}
  raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
  raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
  parser = XPathParser.new
  parser.namespaces = namespaces
  parser.variables = variables
  path = "*" unless path
  element = [element] unless element.kind_of? Array
  parser.parse(path, element).flatten[0]
end
match(element, path=nil, namespaces=nil, variables={}) click to toggle source

Returns an array of nodes matching a given XPath.

# File lib/rexml/xpath.rb, line 71
def XPath::match element, path=nil, namespaces=nil, variables={}
  parser = XPathParser.new
  parser.namespaces = namespaces
  parser.variables = variables
  path = "*" unless path
  element = [element] unless element.kind_of? Array
  parser.parse(path,element)
end


class REXML::XPathParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class REXML::XPathParser

You don't want to use this class. Really. Use XPath, which is a wrapper for this class. Believe me. You don't want to poke around in here. There is strange, dark magic at work in this code. Beware. Go back! Go back while you still can!

In Files

  • lib/rexml/xpath_parser.rb

Parent

Object

Included Modules

  • REXML::XMLTokens

Constants

ALL

Expr takes a stack of path elements and a set of nodes (either a Parent or an Array and returns an Array of matching nodes

ELEMENTS
LITERAL

Public Class Methods

new( ) click to toggle source
# File lib/rexml/xpath_parser.rb, line 49
def initialize( )
  @parser = REXML::Parsers::XPathParser.new
  @namespaces = nil
  @variables = {}
end

Public Instance Methods

[]=( variable_name, value ) click to toggle source
# File lib/rexml/xpath_parser.rb, line 86
def []=( variable_name, value )
  @variables[ variable_name ] = value
end
first( path_stack, node ) click to toggle source

Performs a depth-first (document order) XPath search, and returns the first match. This is the fastest, lightest way to return a single result.

FIXME: This method is incomplete!

# File lib/rexml/xpath_parser.rb, line 95
def first( path_stack, node )
  #puts "#{depth}) Entering match( #{path.inspect}, #{tree.inspect} )"
  return nil if path.size == 0

  case path[0]
  when :document
    # do nothing
    return first( path[1..-1], node )
  when :child
    for c in node.children
      #puts "#{depth}) CHILD checking #{name(c)}"
      r = first( path[1..-1], c )
      #puts "#{depth}) RETURNING #{r.inspect}" if r
      return r if r
    end
  when :qname
    name = path[2]
    #puts "#{depth}) QNAME #{name(tree)} == #{name} (path => #{path.size})"
    if node.name == name
      #puts "#{depth}) RETURNING #{tree.inspect}" if path.size == 3
      return node if path.size == 3
      return first( path[3..-1], node )
    else
      return nil
    end
  when :descendant_or_self
    r = first( path[1..-1], node )
    return r if r
    for c in node.children
      r = first( path, c )
      return r if r
    end
  when :node
    return first( path[1..-1], node )
  when :any
    return first( path[1..-1], node )
  end
  return nil
end
get_first(path, nodeset) click to toggle source
# File lib/rexml/xpath_parser.rb, line 73
def get_first path, nodeset
 #puts "#"*40
 path_stack = @parser.parse( path )
 #puts "PARSE: #{path} => #{path_stack.inspect}"
 #puts "PARSE: nodeset = #{nodeset.inspect}"
 first( path_stack, nodeset )
end
match( path_stack, nodeset ) click to toggle source
# File lib/rexml/xpath_parser.rb, line 136
def match( path_stack, nodeset )
  #puts "MATCH: path_stack = #{path_stack.inspect}"
  #puts "MATCH: nodeset = #{nodeset.inspect}"
  r = expr( path_stack, nodeset )
  #puts "MAIN EXPR => #{r.inspect}"
  r
end
namespaces=( namespaces={} ) click to toggle source
# File lib/rexml/xpath_parser.rb, line 55
def namespaces=( namespaces={} )
  Functions::namespace_context = namespaces
  @namespaces = namespaces
end
parse(path, nodeset) click to toggle source
# File lib/rexml/xpath_parser.rb, line 65
def parse path, nodeset
 #puts "#"*40
 path_stack = @parser.parse( path )
 #puts "PARSE: #{path} => #{path_stack.inspect}"
 #puts "PARSE: nodeset = #{nodeset.inspect}"
 match( path_stack, nodeset )
end
predicate(path, nodeset) click to toggle source
# File lib/rexml/xpath_parser.rb, line 81
def predicate path, nodeset
  path_stack = @parser.parse( path )
  expr( path_stack, nodeset )
end
variables=( vars={} ) click to toggle source
# File lib/rexml/xpath_parser.rb, line 60
def variables=( vars={} )
  Functions::variables = vars
  @variables = vars
end


module RSS - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS

RSS reading and writing

Really Simple Syndication (RSS) is a family of formats that describe 'feeds,' specially constructed XML documents that allow an interested person to subscribe and receive updates from a particular web service. This portion of the standard library provides tooling to read and create these feeds.

The standard library supports RSS 0.91, 1.0, 2.0, and Atom, a related format. Here are some links to the standards documents for these formats:

  • RSS

    • 0.9.1

    • 1.0

    • 2.0

  • Atom

Consuming RSS

If you'd like to read someone's RSS feed with your Ruby code, you've come to the right place. It's really easy to do this, but we'll need the help of open-uri:

require 'rss'
require 'open-uri'

url = 'http://www.ruby-lang.org/en/feeds/news.rss'
open(url) do |rss|
  feed = RSS::Parser.parse(rss)
  puts "Title: #{feed.channel.title}"
  feed.items.each do |item|
    puts "Item: #{item.title}"
  end
end

As you can see, the workhorse is RSS::Parser#parse, which takes the source of the feed and a parameter that performs validation on the feed. We get back an object that has all of the data from our feed, accessible through methods. This example shows getting the title out of the channel element, and looping through the list of items.

Producing RSS

Producing our own RSS feeds is easy as well. Let's make a very basic feed:

require "rss"

rss = RSS::Maker.make("atom") do |maker|
  maker.channel.author = "matz"
  maker.channel.updated = Time.now.to_s
  maker.channel.about = "http://www.ruby-lang.org/en/feeds/news.rss"
  maker.channel.title = "Example Feed"

  maker.items.new_item do |item|
    item.link = "http://www.ruby-lang.org/en/news/2010/12/25/ruby-1-9-2-p136-is-released/"
    item.title = "Ruby 1.9.2-p136 is released"
    item.updated = Time.now.to_s
  end
end

puts rss

As you can see, this is a very Builder-like DSL. This code will spit out an Atom feed with one item. If we needed a second item, we'd make another block with maker.items.new_item and build a second one.

Copyright

Copyright © 2003-2007 Kouhei Sutou <kou@cozmixng.org>

You can redistribute it and/or modify it under the same terms as Ruby.

There is an additional tutorial by the author of RSS at: www.cozmixng.org/~rwiki/?cmd=view;name=RSS+Parser%3A%3ATutorial.en

In Files

  • lib/rss/0.9.rb
  • lib/rss/1.0.rb
  • lib/rss/2.0.rb
  • lib/rss/atom.rb
  • lib/rss/content/1.0.rb
  • lib/rss/content/2.0.rb
  • lib/rss/content.rb
  • lib/rss/converter.rb
  • lib/rss/dublincore/1.0.rb
  • lib/rss/dublincore/2.0.rb
  • lib/rss/dublincore/atom.rb
  • lib/rss/dublincore.rb
  • lib/rss/image.rb
  • lib/rss/itunes.rb
  • lib/rss/maker/0.9.rb
  • lib/rss/maker/1.0.rb
  • lib/rss/maker/2.0.rb
  • lib/rss/maker/atom.rb
  • lib/rss/maker/base.rb
  • lib/rss/maker/content.rb
  • lib/rss/maker/dublincore.rb
  • lib/rss/maker/entry.rb
  • lib/rss/maker/feed.rb
  • lib/rss/maker/image.rb
  • lib/rss/maker/itunes.rb
  • lib/rss/maker/slash.rb
  • lib/rss/maker/syndication.rb
  • lib/rss/maker/taxonomy.rb
  • lib/rss/maker/trackback.rb
  • lib/rss/maker.rb
  • lib/rss/parser.rb
  • lib/rss/rexmlparser.rb
  • lib/rss/rss.rb
  • lib/rss/slash.rb
  • lib/rss/syndication.rb
  • lib/rss/taxonomy.rb
  • lib/rss/trackback.rb
  • lib/rss/utils.rb
  • lib/rss/xml-stylesheet.rb
  • lib/rss/xml.rb
  • lib/rss/xmlparser.rb
  • lib/rss/xmlscanner.rb
  • lib/rss.rb

Constants

AVAILABLE_PARSERS
AVAILABLE_PARSER_LIBRARIES
CONTENT_PREFIX
CONTENT_URI
DC_PREFIX
DC_URI
DEBUG
DublincoreModel

For backward compatibility

IMAGE_ELEMENTS
IMAGE_PREFIX
IMAGE_URI
ITUNES_PREFIX
ITUNES_URI
NotExceptedTagError

For backward compatibility :X

SLASH_PREFIX
SLASH_URI
SY_PREFIX
SY_URI
TAXO_ELEMENTS
TAXO_PREFIX
TAXO_URI
TRACKBACK_PREFIX
TRACKBACK_URI
URI
UnknownConvertMethod

for backward compatibility

VERSION


module RSS::Atom - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Atom

Atom is an XML-based document format that is used to describe 'feeds' of related information. A typical use is in a news feed where the information is periodically updated and which users can subscribe to. The Atom format is described in tools.ietf.org/html/rfc4287

The Atom module provides support in reading and creating feeds.

See the RSS module for examples consuming and creating feeds

In Files

  • lib/rss/atom.rb
  • lib/rss/dublincore/atom.rb

Constants

URI

The Atom URI W3C Namespace

XHTML_URI

The XHTML URI W3C Namespace


module RSS::Atom::CommonModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Atom::CommonModel

In Files

  • lib/rss/atom.rb

Constants

ELEMENTS
NSPOOL

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/atom.rb, line 28
def self.append_features(klass)
  super
  klass.install_must_call_validator("atom", URI)
  [
   ["lang", :xml],
   ["base", :xml],
  ].each do |name, uri, required|
    klass.install_get_attribute(name, uri, required, [nil, :inherit])
  end
  klass.class_eval do
    class << self
      def required_uri
        URI
      end

      def need_parent?
        true
      end
    end
  end
end
need_parent?() click to toggle source
# File lib/rss/atom.rb, line 43
def need_parent?
  true
end
required_uri() click to toggle source
# File lib/rss/atom.rb, line 39
def required_uri
  URI
end


module RSS::Atom::ContentModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Atom::ContentModel

In Files

  • lib/rss/atom.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/atom.rb, line 59
def append_features(klass)
  super
  klass.extend(ClassMethods)
  klass.content_setup(klass.content_type, klass.tag_name)
end

Public Instance Methods

maker_target(target) click to toggle source
# File lib/rss/atom.rb, line 66
def maker_target(target)
  target
end


module RSS::Atom::ContentModel::ClassMethods - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Atom::ContentModel::ClassMethods

In Files

  • lib/rss/atom.rb

Public Instance Methods

content_type() click to toggle source
# File lib/rss/atom.rb, line 53
def content_type
  @content_type ||= nil
end


module RSS::Atom::DateConstruct - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Atom::DateConstruct

Element used to describe an Atom date and time in the ISO 8601 format

Examples:

  • 2013-03-04T15:30:02Z

  • 2013-03-04T10:30:02-05:00

In Files

  • lib/rss/atom.rb

Included Modules

  • RSS::Atom::ContentModel

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/atom.rb, line 214
def self.append_features(klass)
  super
  klass.class_eval do
    @content_type = :w3cdtf
    include(ContentModel)
  end
end

Public Instance Methods

atom_validate(ignore_unknown_element, tags, uri) click to toggle source

Raises NotAvailableValueError if element content is nil

# File lib/rss/atom.rb, line 223
def atom_validate(ignore_unknown_element, tags, uri)
  raise NotAvailableValueError.new(tag_name, "") if content.nil?
end


module RSS::Atom::DuplicateLinkChecker - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Atom::DuplicateLinkChecker

In Files

  • lib/rss/atom.rb

Public Instance Methods

validate_duplicate_links(links) click to toggle source

Checks if there are duplicate links with the same type and hreflang attributes that have an alternate (or empty) rel attribute

Raises a TooMuchTagError if there are duplicates found

# File lib/rss/atom.rb, line 233
def validate_duplicate_links(links)
  link_infos = {}
  links.each do |link|
    rel = link.rel || "alternate"
    next unless rel == "alternate"
    key = [link.hreflang, link.type]
    if link_infos.has_key?(key)
      raise TooMuchTagError.new("link", tag_name)
    end
    link_infos[key] = true
  end
end


class RSS::Atom::Entry - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Entry

Defines a top-level Atom Entry element

In Files

  • lib/rss/atom.rb
  • lib/rss/dublincore/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::RootElementMixin
  • RSS::Atom::CommonModel
  • RSS::Atom::DuplicateLinkChecker
  • RSS::DublinCoreModel

Constants

Author
Category
Content
Contributor
Id
Link
Published
Rights
Source
Summary
Title
Updated

Public Class Methods

new(version=nil, encoding=nil, standalone=nil) click to toggle source

Creates a new Atom Entry element

# File lib/rss/atom.rb, line 749
def initialize(version=nil, encoding=nil, standalone=nil)
  super("1.0", version, encoding, standalone)
  @feed_type = "atom"
  @feed_subtype = "entry"
end

Public Instance Methods

have_author?() click to toggle source

Returns where there are any authors present or there is a source with an author

# File lib/rss/atom.rb, line 767
def have_author?
  authors.any? {|author| !author.to_s.empty?} or
    (source and source.have_author?)
end
items() click to toggle source

Returns the Entry in an array

# File lib/rss/atom.rb, line 756
def items
  [self]
end
setup_maker(maker) click to toggle source

sets up the maker for constructing Entry elements

# File lib/rss/atom.rb, line 761
def setup_maker(maker)
  maker = maker.maker if maker.respond_to?("maker")
  super(maker)
end


class RSS::Atom::Feed - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed

Atom feed element

A Feed has several metadata attributes in addition to a number of Entry child elements

In Files

  • lib/rss/atom.rb
  • lib/rss/dublincore/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::RootElementMixin
  • RSS::Atom::CommonModel
  • RSS::Atom::DuplicateLinkChecker
  • RSS::DublinCoreModel

Public Class Methods

new(version=nil, encoding=nil, standalone=nil) click to toggle source

Creates a new Atom feed

# File lib/rss/atom.rb, line 278
def initialize(version=nil, encoding=nil, standalone=nil)
  super("1.0", version, encoding, standalone)
  @feed_type = "atom"
  @feed_subtype = "feed"
end

Public Instance Methods

have_author?() click to toggle source

Returns true if there are any authors for the feed or any of the Entry child elements have an author

# File lib/rss/atom.rb, line 288
def have_author?
  authors.any? {|author| !author.to_s.empty?} or
    entries.any? {|entry| entry.have_author?(false)}
end


class RSS::Atom::Feed::Author - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Author

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::PersonConstruct


class RSS::Atom::Feed::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Category

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel


class RSS::Atom::Feed::Contributor - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Contributor

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::PersonConstruct


class RSS::Atom::Feed::Entry - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Entry

Defines a child Atom Entry element for an Atom Feed

In Files

  • lib/rss/atom.rb
  • lib/rss/dublincore/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::DuplicateLinkChecker
  • RSS::DublinCoreModel

Constants

Author
Category
Contributor
Id
Link
Rights
Title
Updated

Public Instance Methods

have_author?(check_parent=true) click to toggle source

Returns whether any of the following are true

  • There are any authors in the feed

  • If the parent element has an author and the check_parent parameter was given.

  • There is a source element that has an author

# File lib/rss/atom.rb, line 496
def have_author?(check_parent=true)
  authors.any? {|author| !author.to_s.empty?} or
    (check_parent and @parent and @parent.have_author?) or
    (source and source.have_author?)
end


class RSS::Atom::Feed::Entry::Content - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Entry::Content

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel

Attributes

xml[W]

Public Class Methods

xml_getter() click to toggle source
# File lib/rss/atom.rb, line 533
def xml_getter
  "xml"
end
xml_setter() click to toggle source
# File lib/rss/atom.rb, line 529
def xml_setter
  "xml="
end

Public Instance Methods

atom_validate(ignore_unknown_element, tags, uri) click to toggle source
# File lib/rss/atom.rb, line 575
def atom_validate(ignore_unknown_element, tags, uri)
  if out_of_line?
    raise MissingAttributeError.new(tag_name, "type") if @type.nil?
    unless (content.nil? or content.empty?)
      raise NotAvailableValueError.new(tag_name, content)
    end
  elsif inline_xhtml?
    if @xml.nil?
      raise MissingTagError.new("div", tag_name)
    end
    unless @xml.name == "div" and @xml.uri == XHTML_URI
      raise NotExpectedTagError.new(@xml.name, @xml.uri, tag_name)
    end
  end
end
have_xml_content?() click to toggle source
# File lib/rss/atom.rb, line 549
def have_xml_content?
  inline_xhtml? or inline_other_xml?
end
inline_html?() click to toggle source
# File lib/rss/atom.rb, line 595
def inline_html?
  return false if out_of_line?
  @type == "html" or mime_split == ["text", "html"]
end
inline_other?() click to toggle source
# File lib/rss/atom.rb, line 604
def inline_other?
  return false if out_of_line?
  media_type, subtype = mime_split
  return false if media_type.nil? or subtype.nil?
  true
end
inline_other_base64?() click to toggle source
# File lib/rss/atom.rb, line 634
def inline_other_base64?
  inline_other? and !inline_other_text? and !inline_other_xml?
end
inline_other_text?() click to toggle source
# File lib/rss/atom.rb, line 611
def inline_other_text?
  return false unless inline_other?
  return false if inline_other_xml?

  media_type, = mime_split
  return true if "text" == media_type.downcase
  false
end
inline_other_xml?() click to toggle source
# File lib/rss/atom.rb, line 620
def inline_other_xml?
  return false unless inline_other?

  media_type, subtype = mime_split
  normalized_mime_type = "#{media_type}/#{subtype}".downcase
  if /(?:\+xml|^xml)$/ =~ subtype or
      %w(text/xml-external-parsed-entity
         application/xml-external-parsed-entity
         application/xml-dtd).find {|x| x == normalized_mime_type}
    return true
  end
  false
end
inline_text?() click to toggle source
# File lib/rss/atom.rb, line 591
def inline_text?
  !out_of_line? and [nil, "text", "html"].include?(@type)
end
inline_xhtml?() click to toggle source
# File lib/rss/atom.rb, line 600
def inline_xhtml?
  !out_of_line? and @type == "xhtml"
end
mime_split() click to toggle source
# File lib/rss/atom.rb, line 642
def mime_split
  media_type = subtype = nil
  if /\A\s*([a-z]+)\/([a-z\+]+)\s*(?:;.*)?\z/ =~ @type.to_s
    media_type = $1.downcase
    subtype = $2.downcase
  end
  [media_type, subtype]
end
need_base64_encode?() click to toggle source
# File lib/rss/atom.rb, line 651
def need_base64_encode?
  inline_other_base64?
end
out_of_line?() click to toggle source
# File lib/rss/atom.rb, line 638
def out_of_line?
  not @src.nil?
end
xhtml() click to toggle source
# File lib/rss/atom.rb, line 567
def xhtml
  if inline_xhtml?
    xml
  else
    nil
  end
end
xml() click to toggle source
# File lib/rss/atom.rb, line 553
def xml
  return @xml unless inline_xhtml?
  return @xml if @xml.nil?
  if @xml.is_a?(XML::Element) and
      [@xml.name, @xml.uri] == ["div", XHTML_URI]
    return @xml
  end

  children = @xml
  children = [children] unless children.is_a?(Array)
  XML::Element.new("div", nil, XHTML_URI,
                   {"xmlns" => XHTML_URI}, children)
end


class RSS::Atom::Feed::Entry::Published - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Entry::Published

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::DateConstruct


class RSS::Atom::Feed::Entry::Source - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Entry::Source

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel

Constants

Author
Category
Contributor
Generator
Icon
Id
Link
Logo
Rights
Subtitle
Title
Updated

Public Instance Methods

have_author?() click to toggle source
# File lib/rss/atom.rb, line 694
def have_author?
  !author.to_s.empty?
end


class RSS::Atom::Feed::Entry::Summary - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Entry::Summary

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::TextConstruct


class RSS::Atom::Feed::Generator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Generator

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::ContentModel


class RSS::Atom::Feed::Icon - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Icon

Atom Icon element

Image that provides a visual identification for the Feed. Image should have an aspect ratio of 1:1

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::URIContentModel


class RSS::Atom::Feed::Id - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Id

Atom ID element

Universally Unique Identifier (UUID) for the Feed

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::URIContentModel


class RSS::Atom::Feed::Link - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Link

Defines an Atom Link element

A Link has the following attributes:

  • href

  • rel

  • type

  • hreflang

  • title

  • length

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel


class RSS::Atom::Feed::Logo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Logo

Atom Logo element

Image that provides a visual identification for the Feed. Image should have an aspect ratio of 2:1 (horizontal:vertical)

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::URIContentModel

Public Instance Methods

maker_target(target) click to toggle source
# File lib/rss/atom.rb, line 425
def maker_target(target)
  target.maker.image
end


class RSS::Atom::Feed::Rights - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Rights

Atom Rights element

TextConstruct that contains copyright information regarding the content in an Entry or Feed

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::TextConstruct


class RSS::Atom::Feed::Subtitle - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Subtitle

Atom Subtitle element

TextConstruct that conveys a description or subtitle for a Feed

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::TextConstruct


class RSS::Atom::Feed::Title - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Title

Atom Title element

TextConstruct that conveys a description or title for a feed or Entry

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::TextConstruct


class RSS::Atom::Feed::Updated - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::Feed::Updated

Atom Updated element

DateConstruct indicating the most recent time when an Entry or Feed was modified in a way the publisher considers significant

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::DateConstruct


module RSS::Atom::PersonConstruct - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Atom::PersonConstruct

The PersonConstruct module is used to define a Person Atom element that can be used to describe a person, corporation, or similar entity

The PersonConstruct has a Name, Uri, and Email child elements

In Files

  • lib/rss/atom.rb

Public Class Methods

append_features(klass) click to toggle source

Adds attributes for name, uri, and email to the klass

# File lib/rss/atom.rb, line 172
def self.append_features(klass)
  super
  klass.class_eval do
    [
     ["name", nil],
     ["uri", "?"],
     ["email", "?"],
    ].each do |tag, occurs|
      install_have_attribute_element(tag, URI, occurs, nil, :content)
    end
  end
end

Public Instance Methods

maker_target(target) click to toggle source
# File lib/rss/atom.rb, line 185
def maker_target(target)
  target.__send__("new_#{self.class.name.split(/::/).last.downcase}")
end


class RSS::Atom::PersonConstruct::Email - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::PersonConstruct::Email

The email of the person or entity

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::ContentModel


class RSS::Atom::PersonConstruct::Name - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::PersonConstruct::Name

The name of the person or entity

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::ContentModel


class RSS::Atom::PersonConstruct::Uri - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Atom::PersonConstruct::Uri

The URI of the person or entity

In Files

  • lib/rss/atom.rb

Parent

RSS::Element

Included Modules

  • RSS::Atom::CommonModel
  • RSS::Atom::URIContentModel


module RSS::Atom::TextConstruct - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Atom::TextConstruct

The TextConstruct module is used to define a Text construct Atom element, which is used to store small quantities of human-readable text

The TextConstruct has a type attribute, e.g. text, html, xhtml

In Files

  • lib/rss/atom.rb

Attributes

xhtml[W]

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/atom.rb, line 98
def self.append_features(klass)
  super
  klass.class_eval do
    [
     ["type", ""],
    ].each do |name, uri, required|
      install_get_attribute(name, uri, required, :text_type)
    end

    content_setup
    add_need_initialize_variable("xhtml")

    class << self
      def xml_getter
        "xhtml"
      end

      def xml_setter
        "xhtml="
      end
    end
  end
end
xml_getter() click to toggle source
# File lib/rss/atom.rb, line 111
def xml_getter
  "xhtml"
end
xml_setter() click to toggle source
# File lib/rss/atom.rb, line 115
def xml_setter
  "xhtml="
end

Public Instance Methods

atom_validate(ignore_unknown_element, tags, uri) click to toggle source
# File lib/rss/atom.rb, line 142
def atom_validate(ignore_unknown_element, tags, uri)
  if have_xml_content?
    if @xhtml.nil?
      raise MissingTagError.new("div", tag_name)
    end
    unless [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI]
      raise NotExpectedTagError.new(@xhtml.name, @xhtml.uri, tag_name)
    end
  end
end
have_xml_content?() click to toggle source

Returns true if type is “xhtml”

# File lib/rss/atom.rb, line 138
def have_xml_content?
  @type == "xhtml"
end
xhtml() click to toggle source
# File lib/rss/atom.rb, line 124
def xhtml
  return @xhtml if @xhtml.nil?
  if @xhtml.is_a?(XML::Element) and
      [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI]
    return @xhtml
  end

  children = @xhtml
  children = [children] unless children.is_a?(Array)
  XML::Element.new("div", nil, XHTML_URI,
                   {"xmlns" => XHTML_URI}, children)
end


module RSS::Atom::URIContentModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Atom::URIContentModel

In Files

  • lib/rss/atom.rb

Included Modules

  • RSS::Atom::ContentModel

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/atom.rb, line 83
def append_features(klass)
  super
  klass.class_eval do
    @content_type = [nil, :uri]
    include(ContentModel)
  end
end


module RSS::BaseDublinCoreModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::BaseDublinCoreModel

In Files

  • lib/rss/dublincore.rb

Public Instance Methods

append_features(klass) click to toggle source
# File lib/rss/dublincore.rb, line 8
    def append_features(klass)
      super

      return if klass.instance_of?(Module)
      DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
        plural = plural_name || "#{name}s"
        full_name = "#{DC_PREFIX}_#{name}"
        full_plural_name = "#{DC_PREFIX}_#{plural}"
        klass_name = "DublinCore#{Utils.to_class_name(name)}"
        klass.install_must_call_validator(DC_PREFIX, DC_URI)
        klass.install_have_children_element(name, DC_URI, "*",
                                            full_name, full_plural_name)
        klass.module_eval("          remove_method :#{full_name}
          remove_method :#{full_name}=
          remove_method :set_#{full_name}

          def #{full_name}
            @#{full_name}.first and @#{full_name}.first.value
          end

          def #{full_name}=(new_value)
            @#{full_name}[0] = Utils.new_with_value_if_need(#{klass_name}, new_value)
          end
          alias set_#{full_name} #{full_name}=
", *get_file_and_line_from_caller(0))
      end
      klass.module_eval("        if method_defined?(:date)
          alias date_without_#{DC_PREFIX}_date= date=

          def date=(value)
            self.date_without_#{DC_PREFIX}_date = value
            self.#{DC_PREFIX}_date = value
          end
        else
          alias date #{DC_PREFIX}_date
          alias date= #{DC_PREFIX}_date=
        end

        # For backward compatibility
        alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list
", *get_file_and_line_from_caller(0))
    end


class RSS::BaseListener - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::BaseListener

In Files

  • lib/rss/parser.rb

Parent

Object

Public Class Methods

available_tags(uri) click to toggle source

return the tag_names for setters associated with uri

# File lib/rss/parser.rb, line 196
def available_tags(uri)
  (@@accessor_bases[uri] || {}).keys
end
class_name(uri, tag_name) click to toggle source

retrieve ::class_name for the supplied uri and tag_name If it doesn't exist, capitalize the tag_name

# File lib/rss/parser.rb, line 219
def class_name(uri, tag_name)
  name = (@@class_names[uri] || {})[tag_name]
  return name if name

  tag_name = tag_name.gsub(/[_\-]([a-z]?)/) {$1.upcase}
  tag_name[0, 1].upcase + tag_name[1..-1]
end
getter(uri, tag_name) click to toggle source
# File lib/rss/parser.rb, line 191
def getter(uri, tag_name)
  (@@accessor_bases[uri] || {})[tag_name]
end
install_class_name(uri, tag_name, class_name) click to toggle source

record ::class_name for the supplied uri and tag_name

# File lib/rss/parser.rb, line 212
def install_class_name(uri, tag_name, class_name)
  @@class_names[uri] ||= {}
  @@class_names[uri][tag_name] = class_name
end
install_get_text_element(uri, name, accessor_base) click to toggle source
# File lib/rss/parser.rb, line 227
def install_get_text_element(uri, name, accessor_base)
  install_accessor_base(uri, name, accessor_base)
  def_get_text_element(uri, name, *get_file_and_line_from_caller(1))
end
raise_for_undefined_entity?() click to toggle source
# File lib/rss/parser.rb, line 232
def raise_for_undefined_entity?
  true
end
register_uri(uri, name) click to toggle source

register uri against this name.

# File lib/rss/parser.rb, line 201
def register_uri(uri, name)
  @@registered_uris[name] ||= {}
  @@registered_uris[name][uri] = nil
end
setter(uri, tag_name) click to toggle source

return the setter for the uri, tag_name pair, or nil.

# File lib/rss/parser.rb, line 182
def setter(uri, tag_name)
  _getter = getter(uri, tag_name)
  if _getter
    "#{_getter}="
  else
    nil
  end
end
uri_registered?(uri, name) click to toggle source

test if this uri is registered against this name

# File lib/rss/parser.rb, line 207
def uri_registered?(uri, name)
  @@registered_uris[name].has_key?(uri)
end


module RSS::BaseModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::BaseModel

In Files

  • lib/rss/rss.rb

Included Modules

  • RSS::Utils

Public Instance Methods

install_date_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil) click to toggle source
# File lib/rss/rss.rb, line 271
    def install_date_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil)
      name ||= tag_name
      type ||= :w3cdtf
      disp_name ||= name
      self::ELEMENTS << name
      add_need_initialize_variable(name)
      install_model(tag_name, uri, occurs, name)

      # accessor
      convert_attr_reader name
      date_writer(name, type, disp_name)

      install_element(name) do |n, elem_name|
        <<-EOC
        if @#{n}
          rv = "\#{indent}<#{elem_name}>"
          value = html_escape(@#{n}.#{type})
          if need_convert
            rv << convert(value)
          else
            rv << value
          end
            rv << "</#{elem_name}>"
          rv
        else
          ''
        end
EOC
      end

    end
install_have_attribute_element(tag_name, uri, occurs, name=nil, type=nil) click to toggle source
Alias for: install_have_child_element
install_have_child_element(tag_name, uri, occurs, name=nil, type=nil) click to toggle source
# File lib/rss/rss.rb, line 197
    def install_have_child_element(tag_name, uri, occurs, name=nil, type=nil)
      name ||= tag_name
      add_need_initialize_variable(name)
      install_model(tag_name, uri, occurs, name)

      writer_type, reader_type = type
      def_corresponded_attr_writer name, writer_type
      def_corresponded_attr_reader name, reader_type
      install_element(name) do |n, elem_name|
        <<-EOC
        if @#{n}
          "\#{@#{n}.to_s(need_convert, indent)}"
        else
          ''
        end
EOC
      end
    end
Also aliased as: install_have_attribute_element
install_have_children_element(tag_name, uri, occurs, name=nil, plural_name=nil) click to toggle source
# File lib/rss/rss.rb, line 217
    def install_have_children_element(tag_name, uri, occurs, name=nil, plural_name=nil)
      name ||= tag_name
      plural_name ||= "#{name}s"
      add_have_children_element(name, plural_name)
      add_plural_form(name, plural_name)
      install_model(tag_name, uri, occurs, plural_name, true)

      def_children_accessor(name, plural_name)
      install_element(name, "s") do |n, elem_name|
        <<-EOC
        rv = []
        @#{n}.each do |x|
          value = "\#{x.to_s(need_convert, indent)}"
          rv << value if /\\A\\s*\\z/ !~ value
        end
        rv.join("\n")
EOC
      end
    end
install_text_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil) click to toggle source
# File lib/rss/rss.rb, line 237
    def install_text_element(tag_name, uri, occurs, name=nil, type=nil,
                             disp_name=nil)
      name ||= tag_name
      disp_name ||= name
      self::ELEMENTS << name unless self::ELEMENTS.include?(name)
      add_need_initialize_variable(name)
      install_model(tag_name, uri, occurs, name)

      def_corresponded_attr_writer(name, type, disp_name)
      def_corresponded_attr_reader(name, type || :convert)
      install_element(name) do |n, elem_name|
        <<-EOC
        if respond_to?(:#{n}_content)
          content = #{n}_content
        else
          content = @#{n}
        end
        if content
          rv = "\#{indent}<#{elem_name}>"
          value = html_escape(content)
          if need_convert
            rv << convert(value)
          else
            rv << value
          end
            rv << "</#{elem_name}>"
          rv
        else
          ''
        end
EOC
      end
    end


class RSS::BaseParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::BaseParser

In Files

  • lib/rss/parser.rb

Parent

Object

Public Class Methods

new(rss) click to toggle source
# File lib/rss/parser.rb, line 137
def initialize(rss)
  @listener = self.class.listener.new
  @rss = rss
end
raise_for_undefined_entity?() click to toggle source
# File lib/rss/parser.rb, line 132
def raise_for_undefined_entity?
  listener.raise_for_undefined_entity?
end

Public Instance Methods

do_validate() click to toggle source
# File lib/rss/parser.rb, line 154
def do_validate
  @listener.do_validate
end
do_validate=(new_value) click to toggle source
# File lib/rss/parser.rb, line 158
def do_validate=(new_value)
  @listener.do_validate = new_value
end
ignore_unknown_element() click to toggle source
# File lib/rss/parser.rb, line 146
def ignore_unknown_element
  @listener.ignore_unknown_element
end
ignore_unknown_element=(new_value) click to toggle source
# File lib/rss/parser.rb, line 150
def ignore_unknown_element=(new_value)
  @listener.ignore_unknown_element = new_value
end
parse() click to toggle source
# File lib/rss/parser.rb, line 162
def parse
  if @listener.rss.nil?
    _parse
  end
  @listener.rss
end
rss() click to toggle source
# File lib/rss/parser.rb, line 142
def rss
  @listener.rss
end


module RSS::BaseTrackBackModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::BaseTrackBackModel

In Files

  • lib/rss/trackback.rb

Included Modules

  • RSS::TrackBackUtils

Constants

ELEMENTS

Public Instance Methods

append_features(klass) click to toggle source
# File lib/rss/trackback.rb, line 27
    def append_features(klass)
      super

      unless klass.class == Module
        klass.module_eval {include TrackBackUtils}

        klass.install_must_call_validator(TRACKBACK_PREFIX, TRACKBACK_URI)
        %w(ping).each do |name|
          var_name = "#{TRACKBACK_PREFIX}_#{name}"
          klass_name = "TrackBack#{Utils.to_class_name(name)}"
          klass.install_have_child_element(name, TRACKBACK_URI, "?", var_name)
          klass.module_eval("            remove_method :#{var_name}
            def #{var_name}
              @#{var_name} and @#{var_name}.value
            end

            remove_method :#{var_name}=
            def #{var_name}=(value)
              @#{var_name} = Utils.new_with_value_if_need(#{klass_name}, value)
            end
", __FILE__, __LINE__)
        end

        [%w(about s)].each do |name, postfix|
          var_name = "#{TRACKBACK_PREFIX}_#{name}"
          klass_name = "TrackBack#{Utils.to_class_name(name)}"
          klass.install_have_children_element(name, TRACKBACK_URI, "*",
                                              var_name)
          klass.module_eval("            remove_method :#{var_name}
            def #{var_name}(*args)
              if args.empty?
                @#{var_name}.first and @#{var_name}.first.value
              else
                ret = @#{var_name}.__send__("[]", *args)
                if ret.is_a?(Array)
                  ret.collect {|x| x.value}
                else
                  ret.value
                end
              end
            end

            remove_method :#{var_name}=
            remove_method :set_#{var_name}
            def #{var_name}=(*args)
              if args.size == 1
                item = Utils.new_with_value_if_need(#{klass_name}, args[0])
                @#{var_name}.push(item)
              else
                new_val = args.last
                if new_val.is_a?(Array)
                  new_val = new_value.collect do |val|
                    Utils.new_with_value_if_need(#{klass_name}, val)
                  end
                else
                  new_val = Utils.new_with_value_if_need(#{klass_name}, new_val)
                end
                @#{var_name}.__send__("[]=", *(args[0..-2] + [new_val]))
              end
            end
            alias set_#{var_name} #{var_name}=
", __FILE__, __LINE__)
        end
      end
    end


module RSS::ContentModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::ContentModel

In Files

  • lib/rss/content.rb

Constants

ELEMENTS

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/content.rb, line 12
def self.append_features(klass)
  super

  klass.install_must_call_validator(CONTENT_PREFIX, CONTENT_URI)
  ELEMENTS.each do |full_name|
    name = full_name[(CONTENT_PREFIX.size + 1)..-1]
    klass.install_text_element(name, CONTENT_URI, "?", full_name)
  end
end


class RSS::ConversionError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::ConversionError

Raised when a conversion failure occurs.

In Files

  • lib/rss/rss.rb

Parent

RSS::Error

Attributes

from[R]
string[R]
to[R]

Public Class Methods

new(string, to, from) click to toggle source
# File lib/rss/rss.rb, line 163
def initialize(string, to, from)
  @string = string
  @to = to
  @from = from
  super("can't convert #{@string} to #{to} from #{from}.")
end


class RSS::Converter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Converter

In Files

  • lib/rss/converter.rb

Parent

Object

Included Modules

  • RSS::Utils

Public Class Methods

new(to_enc, from_enc=nil) click to toggle source
# File lib/rss/converter.rb, line 9
def initialize(to_enc, from_enc=nil)
  if "".respond_to?(:encode)
    @to_encoding = to_enc
    return
  end
  normalized_to_enc = to_enc.downcase.gsub(/-/, '_')
  from_enc ||= 'utf-8'
  normalized_from_enc = from_enc.downcase.gsub(/-/, '_')
  if normalized_to_enc == normalized_from_enc
    def_same_enc()
  else
    def_diff_enc = "def_to_#{normalized_to_enc}_from_#{normalized_from_enc}"
    if respond_to?(def_diff_enc)
      __send__(def_diff_enc)
    else
      def_else_enc(to_enc, from_enc)
    end
  end
end

Public Instance Methods

convert(value) click to toggle source
# File lib/rss/converter.rb, line 29
def convert(value)
  if value.is_a?(String) and value.respond_to?(:encode)
    value.encode(@to_encoding)
  else
    value
  end
end
def_convert(depth=0) click to toggle source
# File lib/rss/converter.rb, line 37
    def def_convert(depth=0)
      instance_eval("      def convert(value)
        if value.kind_of?(String)
          #{yield('value')}
        else
          value
        end
      end
", *get_file_and_line_from_caller(depth))
    end
def_else_enc(to_enc, from_enc) click to toggle source
# File lib/rss/converter.rb, line 67
def def_else_enc(to_enc, from_enc)
  def_iconv_convert(to_enc, from_enc, 0)
end
def_iconv_convert(to_enc, from_enc, depth=0) click to toggle source
# File lib/rss/converter.rb, line 49
def def_iconv_convert(to_enc, from_enc, depth=0)
  begin
    require "iconv"
    @iconv = Iconv.new(to_enc, from_enc)
    def_convert(depth+1) do |value|
      <<-EOC
      begin
        @iconv.iconv(#{value})
      rescue Iconv::Failure
        raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}")
      end
      EOC
    end
  rescue LoadError, ArgumentError, SystemCallError
    raise UnknownConversionMethodError.new(to_enc, from_enc)
  end
end
def_same_enc() click to toggle source
# File lib/rss/converter.rb, line 71
def def_same_enc()
  def_convert do |value|
    value
  end
end
def_to_euc_jp_from_iso_2022_jp() click to toggle source
# File lib/rss/converter.rb, line 131
def def_to_euc_jp_from_iso_2022_jp
  require "nkf"
  def_convert do |value|
    "NKF.nkf('-Je', #{value})"
  end
end
def_to_euc_jp_from_shift_jis() click to toggle source
# File lib/rss/converter.rb, line 117
def def_to_euc_jp_from_shift_jis
  require "nkf"
  def_convert do |value|
    "NKF.nkf('-Se', #{value})"
  end
end
def_to_euc_jp_from_utf_8() click to toggle source
# File lib/rss/converter.rb, line 101
def def_to_euc_jp_from_utf_8
  def_uconv_convert_if_can('u8toeuc', 'EUC-JP', 'UTF-8', '-We')
end
def_to_iso_2022_jp_from_euc_jp() click to toggle source
# File lib/rss/converter.rb, line 138
def def_to_iso_2022_jp_from_euc_jp
  require "nkf"
  def_convert do |value|
    "NKF.nkf('-Ej', #{value})"
  end
end
def_to_iso_8859_1_from_utf_8() click to toggle source
# File lib/rss/converter.rb, line 151
def def_to_iso_8859_1_from_utf_8
  def_convert do |value|
    <<-EOC
    array_utf8 = #{value}.unpack('U*')
    array_enc = []
    array_utf8.each do |num|
      if num <= 0xFF
        array_enc << num
      else
        array_enc.concat "&\#\#{num};".unpack('C*')
      end
    end
    array_enc.pack('C*')
    EOC
  end
end
def_to_shift_jis_from_euc_jp() click to toggle source
# File lib/rss/converter.rb, line 124
def def_to_shift_jis_from_euc_jp
  require "nkf"
  def_convert do |value|
    "NKF.nkf('-Es', #{value})"
  end
end
def_to_shift_jis_from_utf_8() click to toggle source
# File lib/rss/converter.rb, line 109
def def_to_shift_jis_from_utf_8
  def_uconv_convert_if_can('u8tosjis', 'Shift_JIS', 'UTF-8', '-Ws')
end
def_to_utf_8_from_euc_jp() click to toggle source
# File lib/rss/converter.rb, line 105
def def_to_utf_8_from_euc_jp
  def_uconv_convert_if_can('euctou8', 'UTF-8', 'EUC-JP', '-Ew')
end
def_to_utf_8_from_iso_8859_1() click to toggle source
# File lib/rss/converter.rb, line 145
def def_to_utf_8_from_iso_8859_1
  def_convert do |value|
    "#{value}.unpack('C*').pack('U*')"
  end
end
def_to_utf_8_from_shift_jis() click to toggle source
# File lib/rss/converter.rb, line 113
def def_to_utf_8_from_shift_jis
  def_uconv_convert_if_can('sjistou8', 'UTF-8', 'Shift_JIS', '-Sw')
end
def_uconv_convert_if_can(meth, to_enc, from_enc, nkf_arg) click to toggle source
# File lib/rss/converter.rb, line 77
def def_uconv_convert_if_can(meth, to_enc, from_enc, nkf_arg)
  begin
    require "uconv"
    def_convert(1) do |value|
      <<-EOC
      begin
        Uconv.#{meth}(#{value})
      rescue Uconv::Error
        raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}")
      end
      EOC
    end
  rescue LoadError
    require 'nkf'
    if NKF.const_defined?(:UTF8)
      def_convert(1) do |value|
        "NKF.nkf(#{nkf_arg.dump}, #{value})"
      end
    else
      def_iconv_convert(to_enc, from_enc, 1)
    end
  end
end


module RSS::DublincoreModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::DublincoreModel

In Files

  • lib/rss/dublincore.rb

Constants

DATE_ELEMENTS
ELEMENTS
ELEMENT_NAME_INFOS
TEXT_ELEMENTS


class RSS::Element - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Element

In Files

  • lib/rss/rss.rb

Parent

Object

Included Modules

  • RSS::Utils
  • RSS::SetupMaker

Constants

GET_ATTRIBUTES
HAVE_CHILDREN_ELEMENTS
INDENT
MODELS
MUST_CALL_VALIDATORS
NEED_INITIALIZE_VARIABLES
PLURAL_FORMS
TO_ELEMENT_METHODS

Attributes

do_validate[RW]
parent[RW]

Public Class Methods

add_have_children_element(variable_name, plural_name) click to toggle source
# File lib/rss/rss.rb, line 804
def add_have_children_element(variable_name, plural_name)
  self::HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name]
end
add_need_initialize_variable(variable_name) click to toggle source
# File lib/rss/rss.rb, line 812
def add_need_initialize_variable(variable_name)
  self::NEED_INITIALIZE_VARIABLES << variable_name
end
add_plural_form(singular, plural) click to toggle source
# File lib/rss/rss.rb, line 816
def add_plural_form(singular, plural)
  self::PLURAL_FORMS[singular] = plural
end
add_to_element_method(method_name) click to toggle source
# File lib/rss/rss.rb, line 808
def add_to_element_method(method_name)
  self::TO_ELEMENT_METHODS << method_name
end
content_setup(type=nil, disp_name=nil) click to toggle source
# File lib/rss/rss.rb, line 793
def content_setup(type=nil, disp_name=nil)
  writer_type, reader_type = type
  def_corresponded_attr_writer :content, writer_type, disp_name
  def_corresponded_attr_reader :content, reader_type
  @have_content = true
end
def_corresponded_attr_reader(name, type=nil) click to toggle source
# File lib/rss/rss.rb, line 774
def def_corresponded_attr_reader(name, type=nil)
  case type
  when :inherit
    inherit_convert_attr_reader name
  when :uri
    uri_convert_attr_reader name
  when :yes_clean_other
    yes_clean_other_attr_reader name
  when :yes_other
    yes_other_attr_reader name
  when :csv
    csv_attr_reader name
  when :csv_integer
    csv_attr_reader name, :separator => ","
  else
    convert_attr_reader name
  end
end
def_corresponded_attr_writer(name, type=nil, disp_name=nil) click to toggle source
# File lib/rss/rss.rb, line 746
def def_corresponded_attr_writer(name, type=nil, disp_name=nil)
  disp_name ||= name
  case type
  when :integer
    integer_writer name, disp_name
  when :positive_integer
    positive_integer_writer name, disp_name
  when :boolean
    boolean_writer name, disp_name
  when :w3cdtf, :rfc822, :rfc2822
    date_writer name, type, disp_name
  when :text_type
    text_type_writer name, disp_name
  when :content
    content_writer name, disp_name
  when :yes_clean_other
    yes_clean_other_writer name, disp_name
  when :yes_other
    yes_other_writer name, disp_name
  when :csv
    csv_writer name
  when :csv_integer
    csv_integer_writer name
  else
    attr_writer name
  end
end
get_attributes() click to toggle source
# File lib/rss/rss.rb, line 683
def get_attributes
  inherited_array_reader("GET_ATTRIBUTES")
end
have_children_elements() click to toggle source
# File lib/rss/rss.rb, line 686
def have_children_elements
  inherited_array_reader("HAVE_CHILDREN_ELEMENTS")
end
have_content?() click to toggle source
# File lib/rss/rss.rb, line 800
def have_content?
  @have_content
end
inherited(klass) click to toggle source
# File lib/rss/rss.rb, line 703
def inherited(klass)
  klass.const_set(:MUST_CALL_VALIDATORS, {})
  klass.const_set(:MODELS, [])
  klass.const_set(:GET_ATTRIBUTES, [])
  klass.const_set(:HAVE_CHILDREN_ELEMENTS, [])
  klass.const_set(:TO_ELEMENT_METHODS, [])
  klass.const_set(:NEED_INITIALIZE_VARIABLES, [])
  klass.const_set(:PLURAL_FORMS, {})

  tag_name = klass.name.split(/::/).last
  tag_name[0, 1] = tag_name[0, 1].downcase
  klass.instance_variable_set(:@tag_name, tag_name)
  klass.instance_variable_set(:@have_content, false)
end
inherited_base() click to toggle source
# File lib/rss/rss.rb, line 699
def inherited_base
  ::RSS::Element
end
install_get_attribute(name, uri, required=true, type=nil, disp_name=nil, element_name=nil) click to toggle source
# File lib/rss/rss.rb, line 731
def install_get_attribute(name, uri, required=true,
                          type=nil, disp_name=nil,
                          element_name=nil)
  disp_name ||= name
  element_name ||= name
  writer_type, reader_type = type
  def_corresponded_attr_writer name, writer_type, disp_name
  def_corresponded_attr_reader name, reader_type
  if type == :boolean and /^is/ =~ name
    alias_method "#{$POSTMATCH}?", name
  end
  self::GET_ATTRIBUTES << [name, uri, required, element_name]
  add_need_initialize_variable(disp_name)
end
install_model(tag, uri, occurs=nil, getter=nil, plural=false) click to toggle source
# File lib/rss/rss.rb, line 722
def install_model(tag, uri, occurs=nil, getter=nil, plural=false)
  getter ||= tag
  if m = self::MODELS.find {|t, u, o, g, p| t == tag and u == uri}
    m[2] = occurs
  else
    self::MODELS << [tag, uri, occurs, getter, plural]
  end
end
install_must_call_validator(prefix, uri) click to toggle source
# File lib/rss/rss.rb, line 718
def install_must_call_validator(prefix, uri)
  self::MUST_CALL_VALIDATORS[uri] = prefix
end
install_ns(prefix, uri) click to toggle source
# File lib/rss/rss.rb, line 832
def install_ns(prefix, uri)
  if self::NSPOOL.has_key?(prefix)
    raise OverlappedPrefixError.new(prefix)
  end
  self::NSPOOL[prefix] = uri
end
models() click to toggle source
# File lib/rss/rss.rb, line 680
def models
  inherited_array_reader("MODELS")
end
must_call_validators() click to toggle source
# File lib/rss/rss.rb, line 677
def must_call_validators
  inherited_hash_reader("MUST_CALL_VALIDATORS")
end
need_initialize_variables() click to toggle source
# File lib/rss/rss.rb, line 692
def need_initialize_variables
  inherited_array_reader("NEED_INITIALIZE_VARIABLES")
end
need_parent?() click to toggle source
# File lib/rss/rss.rb, line 828
def need_parent?
  false
end
new(do_validate=true, attrs=nil) click to toggle source
# File lib/rss/rss.rb, line 846
def initialize(do_validate=true, attrs=nil)
  @parent = nil
  @converter = nil
  if attrs.nil? and (do_validate.is_a?(Hash) or do_validate.is_a?(Array))
    do_validate, attrs = true, do_validate
  end
  @do_validate = do_validate
  initialize_variables(attrs || {})
end
plural_forms() click to toggle source
# File lib/rss/rss.rb, line 695
def plural_forms
  inherited_hash_reader("PLURAL_FORMS")
end
required_prefix() click to toggle source
# File lib/rss/rss.rb, line 820
def required_prefix
  nil
end
required_uri() click to toggle source
# File lib/rss/rss.rb, line 824
def required_uri
  ""
end
tag_name() click to toggle source
# File lib/rss/rss.rb, line 839
def tag_name
  @tag_name
end
to_element_methods() click to toggle source
# File lib/rss/rss.rb, line 689
def to_element_methods
  inherited_array_reader("TO_ELEMENT_METHODS")
end

Public Instance Methods

convert(value) click to toggle source
# File lib/rss/rss.rb, line 875
def convert(value)
  if @converter
    @converter.convert(value)
  else
    value
  end
end
converter=(converter) click to toggle source
# File lib/rss/rss.rb, line 864
def converter=(converter)
  @converter = converter
  targets = children.dup
  self.class.have_children_elements.each do |variable_name, plural_name|
    targets.concat(__send__(plural_name))
  end
  targets.each do |target|
    target.converter = converter unless target.nil?
  end
end
full_name() click to toggle source
# File lib/rss/rss.rb, line 860
def full_name
  tag_name
end
have_xml_content?() click to toggle source
# File lib/rss/rss.rb, line 925
def have_xml_content?
  false
end
need_base64_encode?() click to toggle source
# File lib/rss/rss.rb, line 929
def need_base64_encode?
  false
end
set_next_element(tag_name, next_element) click to toggle source
# File lib/rss/rss.rb, line 933
def set_next_element(tag_name, next_element)
  klass = next_element.class
  prefix = ""
  prefix << "#{klass.required_prefix}_" if klass.required_prefix
  key = "#{prefix}#{tag_name.gsub(/-/, '_')}"
  if self.class.plural_forms.has_key?(key)
    ary = __send__("#{self.class.plural_forms[key]}")
    ary << next_element
  else
    __send__("#{key}=", next_element)
  end
end
tag_name() click to toggle source
# File lib/rss/rss.rb, line 856
def tag_name
  self.class.tag_name
end
to_s(need_convert=true, indent='') click to toggle source
# File lib/rss/rss.rb, line 904
def to_s(need_convert=true, indent='')
  if self.class.have_content?
    return "" if !empty_content? and !content_is_set?
    rv = tag(indent) do |next_indent|
      if empty_content?
        ""
      else
        xmled_content
      end
    end
  else
    rv = tag(indent) do |next_indent|
      self.class.to_element_methods.collect do |method_name|
        __send__(method_name, false, next_indent)
      end
    end
  end
  rv = convert(rv) if need_convert
  rv
end
valid?(ignore_unknown_element=true) click to toggle source
# File lib/rss/rss.rb, line 883
def valid?(ignore_unknown_element=true)
  validate(ignore_unknown_element)
  true
rescue RSS::Error
  false
end
validate(ignore_unknown_element=true) click to toggle source
# File lib/rss/rss.rb, line 890
def validate(ignore_unknown_element=true)
  do_validate = @do_validate
  @do_validate = true
  validate_attribute
  __validate(ignore_unknown_element)
ensure
  @do_validate = do_validate
end
validate_for_stream(tags, ignore_unknown_element=true) click to toggle source
# File lib/rss/rss.rb, line 899
def validate_for_stream(tags, ignore_unknown_element=true)
  validate_attribute
  __validate(ignore_unknown_element, tags, false)
end

Protected Instance Methods

have_required_elements?() click to toggle source
# File lib/rss/rss.rb, line 947
def have_required_elements?
  self.class::MODELS.all? do |tag, uri, occurs, getter|
    if occurs.nil? or occurs == "+"
      child = __send__(getter)
      if child.is_a?(Array)
        children = child
        children.any? {|c| c.have_required_elements?}
      else
        !child.to_s.empty?
      end
    else
      true
    end
  end
end


class RSS::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Error

In Files

  • lib/rss/rss.rb

Parent

StandardError


module RSS::ITunesBaseModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::ITunesBaseModel

In Files

  • lib/rss/itunes.rb

Constants

ELEMENTS
ELEMENT_INFOS


module RSS::ITunesChannelModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::ITunesChannelModel

In Files

  • lib/rss/itunes.rb

Included Modules

  • RSS::ITunesBaseModel

Constants

ELEMENTS
ELEMENT_INFOS

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/itunes.rb, line 65
def append_features(klass)
  super

  return if klass.instance_of?(Module)
  ELEMENT_INFOS.each do |name, type, *additional_infos|
    def_class_accessor(klass, name, type, *additional_infos)
  end
end


class RSS::ITunesChannelModel::ITunesCategory - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::ITunesChannelModel::ITunesCategory

In Files

  • lib/rss/itunes.rb

Parent

Element

Included Modules

  • RSS::RSS09

Constants

ITunesCategory

Public Class Methods

new(*args) click to toggle source
# File lib/rss/itunes.rb, line 108
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.text = args[0]
  end
end
required_prefix() click to toggle source
# File lib/rss/itunes.rb, line 88
def required_prefix
  ITUNES_PREFIX
end
required_uri() click to toggle source
# File lib/rss/itunes.rb, line 92
def required_uri
  ITUNES_URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/itunes.rb, line 117
def full_name
  tag_name_with_prefix(ITUNES_PREFIX)
end


class RSS::ITunesChannelModel::ITunesImage - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::ITunesChannelModel::ITunesImage

In Files

  • lib/rss/itunes.rb

Parent

Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/itunes.rb, line 163
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.href = args[0]
  end
end
required_prefix() click to toggle source
# File lib/rss/itunes.rb, line 148
def required_prefix
  ITUNES_PREFIX
end
required_uri() click to toggle source
# File lib/rss/itunes.rb, line 152
def required_uri
  ITUNES_URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/itunes.rb, line 172
def full_name
  tag_name_with_prefix(ITUNES_PREFIX)
end


class RSS::ITunesChannelModel::ITunesOwner - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::ITunesChannelModel::ITunesOwner

In Files

  • lib/rss/itunes.rb

Parent

Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/itunes.rb, line 214
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.itunes_name = args[0]
    self.itunes_email = args[1]
  end
end
required_prefix() click to toggle source
# File lib/rss/itunes.rb, line 196
def required_prefix
  ITUNES_PREFIX
end
required_uri() click to toggle source
# File lib/rss/itunes.rb, line 200
def required_uri
  ITUNES_URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/itunes.rb, line 224
def full_name
  tag_name_with_prefix(ITUNES_PREFIX)
end


module RSS::ITunesItemModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::ITunesItemModel

In Files

  • lib/rss/itunes.rb

Included Modules

  • RSS::ITunesBaseModel

Constants

ELEMENT_INFOS

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/itunes.rb, line 247
def append_features(klass)
  super

  return if klass.instance_of?(Module)
  ELEMENT_INFOS.each do |name, type|
    def_class_accessor(klass, name, type)
  end
end


class RSS::ITunesItemModel::ITunesDuration - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::ITunesItemModel::ITunesDuration

In Files

  • lib/rss/itunes.rb

Parent

Element

Included Modules

  • RSS::RSS09

Attributes

hour[R]
minute[R]
second[R]

Public Class Methods

construct(hour, minute, second) click to toggle source
# File lib/rss/itunes.rb, line 294
def construct(hour, minute, second)
  components = [minute, second]
  if components.include?(nil)
    nil
  else
    components.unshift(hour) if hour and hour > 0
    components.collect do |component|
      "%02d" % component
    end.join(":")
  end
end
new(*args) click to toggle source
# File lib/rss/itunes.rb, line 312
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    args = args[0] if args.size == 1 and args[0].is_a?(Array)
    if args.size == 1
      self.content = args[0]
    elsif args.size > 3
      raise ArgumentError,
              "must be (do_validate, params), (content), " +
              "(minute, second), ([minute, second]), "  +
              "(hour, minute, second) or ([hour, minute, second]): " +
              args.inspect
    else
      @second, @minute, @hour = args.reverse
      update_content
    end
  end
end
parse(duration, do_validate=true) click to toggle source
# File lib/rss/itunes.rb, line 274
def parse(duration, do_validate=true)
  if do_validate and /\A(?:
                          \d?\d:[0-5]\d:[0-5]\d|
                          [0-5]?\d:[0-5]\d
                        )\z/ !~ duration
    raise ArgumentError,
            "must be one of HH:MM:SS, H:MM:SS, MM::SS, M:SS: " +
            duration.inspect
  end

  components = duration.split(':')
  components[3..-1] = nil if components.size > 3

  components.unshift("00") until components.size == 3

  components.collect do |component|
    component.to_i
  end
end
required_prefix() click to toggle source
# File lib/rss/itunes.rb, line 266
def required_prefix
  ITUNES_PREFIX
end
required_uri() click to toggle source
# File lib/rss/itunes.rb, line 270
def required_uri
  ITUNES_URI
end

Public Instance Methods

content=(value) click to toggle source
# File lib/rss/itunes.rb, line 333
def content=(value)
  if value.nil?
    @content = nil
  elsif value.is_a?(self.class)
    self.content = value.content
  else
    begin
      @hour, @minute, @second = self.class.parse(value, @do_validate)
    rescue ArgumentError
      raise NotAvailableValueError.new(tag_name, value)
    end
    @content = value
  end
end
Also aliased as: value=
full_name() click to toggle source
# File lib/rss/itunes.rb, line 367
def full_name
  tag_name_with_prefix(ITUNES_PREFIX)
end
hour=(hour) click to toggle source
# File lib/rss/itunes.rb, line 349
def hour=(hour)
  @hour = @do_validate ? Integer(hour) : hour.to_i
  update_content
  hour
end
minute=(minute) click to toggle source
# File lib/rss/itunes.rb, line 355
def minute=(minute)
  @minute = @do_validate ? Integer(minute) : minute.to_i
  update_content
  minute
end
second=(second) click to toggle source
# File lib/rss/itunes.rb, line 361
def second=(second)
  @second = @do_validate ? Integer(second) : second.to_i
  update_content
  second
end
value=(value) click to toggle source
Alias for: content=


module RSS::ITunesModelUtils - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::ITunesModelUtils

In Files

  • lib/rss/itunes.rb

Included Modules

  • RSS::Utils

Public Instance Methods

def_class_accessor(klass, name, type, *args) click to toggle source
# File lib/rss/itunes.rb, line 12
def def_class_accessor(klass, name, type, *args)
    normalized_name = name.gsub(/-/, "_")
  full_name = "#{ITUNES_PREFIX}_#{normalized_name}"
  klass_name = "ITunes#{Utils.to_class_name(normalized_name)}"

  case type
  when :element, :attribute
    klass::ELEMENTS << full_name
    def_element_class_accessor(klass, name, full_name, klass_name, *args)
  when :elements
    klass::ELEMENTS << full_name
    def_elements_class_accessor(klass, name, full_name, klass_name, *args)
  else
    klass.install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)
    klass.install_text_element(normalized_name, ITUNES_URI, "?",
                               full_name, type, name)
  end
end
def_element_class_accessor(klass, name, full_name, klass_name, recommended_attribute_name=nil) click to toggle source
# File lib/rss/itunes.rb, line 31
def def_element_class_accessor(klass, name, full_name, klass_name,
                               recommended_attribute_name=nil)
  klass.install_have_child_element(name, ITUNES_PREFIX, "?", full_name)
end
def_elements_class_accessor(klass, name, full_name, klass_name, plural_name, recommended_attribute_name=nil) click to toggle source
# File lib/rss/itunes.rb, line 36
def def_elements_class_accessor(klass, name, full_name, klass_name,
                                plural_name, recommended_attribute_name=nil)
  full_plural_name = "#{ITUNES_PREFIX}_#{plural_name}"
  klass.install_have_children_element(name, ITUNES_PREFIX, "*",
                                      full_name, full_plural_name)
end


module RSS::ImageFaviconModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::ImageFaviconModel

In Files

  • lib/rss/image.rb

Included Modules

  • RSS::ImageModelUtils

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/image.rb, line 110
def self.append_features(klass)
  super

  unless klass.class == Module
    klass.install_have_child_element("favicon", IMAGE_URI, "?",
                                     "#{IMAGE_PREFIX}_favicon")
    klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
  end
end


class RSS::ImageFaviconModel::ImageFavicon - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::ImageFaviconModel::ImageFavicon

In Files

  • lib/rss/image.rb

Parent

Element

Included Modules

  • RSS::RSS10
  • RSS::DublinCoreModel

Constants

AVAILABLE_SIZES

Public Class Methods

new(*args) click to toggle source
# File lib/rss/image.rb, line 161
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.about = args[0]
    self.size = args[1]
  end
end
required_prefix() click to toggle source
# File lib/rss/image.rb, line 127
def required_prefix
  IMAGE_PREFIX
end
required_uri() click to toggle source
# File lib/rss/image.rb, line 131
def required_uri
  IMAGE_URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/image.rb, line 171
def full_name
  tag_name_with_prefix(IMAGE_PREFIX)
end
image_size=(new_value) click to toggle source
Alias for: size=
set_size(new_value) click to toggle source
Alias for: size=
size=(new_value) click to toggle source
# File lib/rss/image.rb, line 147
def size=(new_value)
  if @do_validate and !new_value.nil?
    new_value = new_value.strip
    unless AVAILABLE_SIZES.include?(new_value)
      attr_name = "#{IMAGE_PREFIX}:size"
      raise NotAvailableValueError.new(full_name, new_value, attr_name)
    end
  end
  set_size(new_value)
end
Also aliased as: set_size, image_size=


module RSS::ImageItemModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::ImageItemModel

In Files

  • lib/rss/image.rb

Included Modules

  • RSS::ImageModelUtils

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/image.rb, line 33
def self.append_features(klass)
  super

  klass.install_have_child_element("item", IMAGE_URI, "?",
                                   "#{IMAGE_PREFIX}_item")
  klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
end


class RSS::ImageItemModel::ImageItem - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::ImageItemModel::ImageItem

In Files

  • lib/rss/image.rb

Parent

Element

Included Modules

  • RSS::RSS10
  • RSS::DublinCoreModel

Public Class Methods

new(*args) click to toggle source
# File lib/rss/image.rb, line 80
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.about = args[0]
    self.resource = args[1]
  end
end
required_prefix() click to toggle source
# File lib/rss/image.rb, line 48
def required_prefix
  IMAGE_PREFIX
end
required_uri() click to toggle source
# File lib/rss/image.rb, line 52
def required_uri
  IMAGE_URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/image.rb, line 90
def full_name
  tag_name_with_prefix(IMAGE_PREFIX)
end


module RSS::ImageModelUtils - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::ImageModelUtils

In Files

  • lib/rss/image.rb

Public Instance Methods

validate_one_tag_name(ignore_unknown_element, name, tags) click to toggle source
# File lib/rss/image.rb, line 20
def validate_one_tag_name(ignore_unknown_element, name, tags)
  if !ignore_unknown_element
    invalid = tags.find {|tag| tag != name}
    raise UnknownTagError.new(invalid, IMAGE_URI) if invalid
  end
  raise TooMuchTagError.new(name, tag_name) if tags.size > 1
end


class RSS::InvalidRSSError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::InvalidRSSError

In Files

  • lib/rss/rss.rb

Parent

RSS::Error


module RSS::ListenerMixin - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::ListenerMixin

In Files

  • lib/rss/0.9.rb
  • lib/rss/1.0.rb
  • lib/rss/atom.rb
  • lib/rss/parser.rb

Constants

CONTENT_PATTERN
NAMESPLIT

Attributes

do_validate[RW]
ignore_unknown_element[RW]
rss[R]

Public Class Methods

new() click to toggle source
# File lib/rss/parser.rb, line 267
def initialize
  @rss = nil
  @ignore_unknown_element = true
  @do_validate = true
  @ns_stack = [{"xml" => :xml}]
  @tag_stack = [[]]
  @text_stack = ['']
  @proc_stack = []
  @last_element = nil
  @version = @encoding = @standalone = nil
  @xml_stylesheets = []
  @xml_child_mode = false
  @xml_element = nil
  @last_xml_element = nil
end

Public Instance Methods

instruction(name, content) click to toggle source
# File lib/rss/parser.rb, line 288
def instruction(name, content)
  if name == "xml-stylesheet"
    params = parse_pi_content(content)
    if params.has_key?("href")
      @xml_stylesheets << XMLStyleSheet.new(params)
    end
  end
end
tag_end(name) click to toggle source
# File lib/rss/parser.rb, line 350
def tag_end(name)
  if DEBUG
    p "end tag #{name}"
    p @tag_stack
  end
  text = @text_stack.pop
  tags = @tag_stack.pop
  pr = @proc_stack.pop
  pr.call(text, tags) unless pr.nil?
  @ns_stack.pop
end
tag_start(name, attributes) click to toggle source
# File lib/rss/parser.rb, line 297
def tag_start(name, attributes)
  @text_stack.push('')

  ns = @ns_stack.last.dup
  attrs = {}
  attributes.each do |n, v|
    if /\Axmlns(?:\z|:)/ =~ n
      ns[$POSTMATCH] = v
    else
      attrs[n] = v
    end
  end
  @ns_stack.push(ns)

  prefix, local = split_name(name)
  @tag_stack.last.push([_ns(ns, prefix), local])
  @tag_stack.push([])
  if @xml_child_mode
    previous = @last_xml_element
    element_attrs = attributes.dup
    unless previous
      ns.each do |ns_prefix, value|
        next if ns_prefix == "xml"
        key = ns_prefix.empty? ? "xmlns" : "xmlns:#{ns_prefix}"
        element_attrs[key] ||= value
      end
    end
    next_element = XML::Element.new(local,
                                    prefix.empty? ? nil : prefix,
                                    _ns(ns, prefix),
                                    element_attrs)
    previous << next_element if previous
    @last_xml_element = next_element
    pr = Proc.new do |text, tags|
      if previous
        @last_xml_element = previous
      else
        @xml_element = @last_xml_element
        @last_xml_element = nil
      end
    end
    @proc_stack.push(pr)
  else
    if @rss.nil? and respond_to?("initial_start_#{local}", true)
      __send__("initial_start_#{local}", local, prefix, attrs, ns.dup)
    elsif respond_to?("start_#{local}", true)
      __send__("start_#{local}", local, prefix, attrs, ns.dup)
    else
      start_else_element(local, prefix, attrs, ns.dup)
    end
  end
end
text(data) click to toggle source
# File lib/rss/parser.rb, line 362
def text(data)
  if @xml_child_mode
    @last_xml_element << data if @last_xml_element
  else
    @text_stack.last << data
  end
end
xmldecl(version, encoding, standalone) click to toggle source

set instance vars for version, encoding, standalone

# File lib/rss/parser.rb, line 284
def xmldecl(version, encoding, standalone)
  @version, @encoding, @standalone = version, encoding, standalone
end


module RSS::Maker - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker

Provides a set of builders for various RSS objects

  • Feeds

    • RSS 0.91

    • RSS 1.0

    • RSS 2.0

    • Atom 1.0

  • Elements

    • Atom::Entry

In Files

  • lib/rss/maker/0.9.rb
  • lib/rss/maker/1.0.rb
  • lib/rss/maker/2.0.rb
  • lib/rss/maker/atom.rb
  • lib/rss/maker/base.rb
  • lib/rss/maker/content.rb
  • lib/rss/maker/dublincore.rb
  • lib/rss/maker/entry.rb
  • lib/rss/maker/feed.rb
  • lib/rss/maker/image.rb
  • lib/rss/maker/itunes.rb
  • lib/rss/maker/slash.rb
  • lib/rss/maker/syndication.rb
  • lib/rss/maker/taxonomy.rb
  • lib/rss/maker/trackback.rb
  • lib/rss/maker.rb

Constants

MAKERS

Collection of supported makers

Public Class Methods

[](version) click to toggle source

Returns the maker for the version

# File lib/rss/maker.rb, line 32
def [](version)
  maker_info = maker(version)
  raise UnsupportedMakerVersionError.new(version) if maker_info.nil?
  maker_info[:maker]
end
add_maker(version, normalized_version, maker) click to toggle source

Adds a maker to the set of supported makers

# File lib/rss/maker.rb, line 39
def add_maker(version, normalized_version, maker)
  MAKERS[version] = {:maker => maker, :version => normalized_version}
end
make(version, &block) click to toggle source

Builder for an RSS object Creates an object of the type passed in args

Executes the block to populate elements of the created RSS object

# File lib/rss/maker.rb, line 27
def make(version, &block)
  self[version].make(&block)
end
makers() click to toggle source

Returns collection of supported makers

# File lib/rss/maker.rb, line 49
def makers
  MAKERS.values.collect { |info| info[:maker] }.uniq
end
supported?(version) click to toggle source

Returns true if the version is supported

# File lib/rss/maker.rb, line 54
def supported?(version)
  versions.include?(version)
end
versions() click to toggle source

Returns collection of supported maker versions

# File lib/rss/maker.rb, line 44
def versions
  MAKERS.keys.uniq.sort
end


module RSS::Maker::Atom - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::Atom

In Files

  • lib/rss/maker/entry.rb
  • lib/rss/maker/feed.rb


class RSS::Maker::Atom::Entry - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry

In Files

  • lib/rss/maker/entry.rb

Parent

RSS::Maker::RSSBase

Public Class Methods

new(feed_version="1.0") click to toggle source
# File lib/rss/maker/entry.rb, line 8
def initialize(feed_version="1.0")
  super
  @feed_type = "atom"
  @feed_subtype = "entry"
end


class RSS::Maker::Atom::Entry::Channel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Channel

In Files

  • lib/rss/maker/entry.rb

Parent

RSS::Maker::ChannelBase

Constants

Authors
Categories
Contributors
Copyright
Links
Title


class RSS::Maker::Atom::Entry::Channel::Cloud - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Channel::Cloud

In Files

  • lib/rss/maker/entry.rb

Parent

CloudBase


class RSS::Maker::Atom::Entry::Channel::Description - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Channel::Description

In Files

  • lib/rss/maker/entry.rb

Parent

DescriptionBase


class RSS::Maker::Atom::Entry::Channel::Generator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Channel::Generator

In Files

  • lib/rss/maker/entry.rb

Parent

GeneratorBase

Included Modules

  • RSS::Maker::AtomGenerator

Public Class Methods

not_set_name() click to toggle source
# File lib/rss/maker/entry.rb, line 45
def self.not_set_name
  "maker.channel.generator"
end


class RSS::Maker::Atom::Entry::Channel::SkipDays - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Channel::SkipDays

In Files

  • lib/rss/maker/entry.rb

Parent

SkipDaysBase


class RSS::Maker::Atom::Entry::Channel::SkipDays::Day - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Channel::SkipDays::Day

In Files

  • lib/rss/maker/entry.rb

Parent

DayBase


class RSS::Maker::Atom::Entry::Channel::SkipHours - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Channel::SkipHours

In Files

  • lib/rss/maker/entry.rb

Parent

SkipHoursBase


class RSS::Maker::Atom::Entry::Channel::SkipHours::Hour - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Channel::SkipHours::Hour

In Files

  • lib/rss/maker/entry.rb

Parent

HourBase


class RSS::Maker::Atom::Entry::Image - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Image

In Files

  • lib/rss/maker/entry.rb

Parent

RSS::Maker::ImageBase


class RSS::Maker::Atom::Entry::Items - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Items

In Files

  • lib/rss/maker/entry.rb

Parent

RSS::Maker::ItemsBase

Public Instance Methods

to_feed(entry) click to toggle source
# File lib/rss/maker/entry.rb, line 62
def to_feed(entry)
  (normalize.first || Item.new(@maker)).to_feed(entry)
end


class RSS::Maker::Atom::Entry::Items::Item - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Items::Item

In Files

  • lib/rss/maker/entry.rb

Parent

ItemBase

Constants

Authors
Categories
Content
Contributors
Description
Enclosure
Guid
Links
Rights
Source
Title

Public Instance Methods

to_feed(entry) click to toggle source
# File lib/rss/maker/entry.rb, line 67
def to_feed(entry)
  set_default_values do
    setup_values(entry)
    entry.dc_dates.clear
    setup_other_elements(entry)
    unless have_required_values?
      raise NotSetError.new("maker.item", not_set_required_variables)
    end
  end
end


class RSS::Maker::Atom::Entry::Textinput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Entry::Textinput

In Files

  • lib/rss/maker/entry.rb

Parent

RSS::Maker::TextinputBase


class RSS::Maker::Atom::Feed - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed

In Files

  • lib/rss/maker/feed.rb

Parent

RSS::Maker::RSSBase

Public Class Methods

new(feed_version="1.0") click to toggle source
# File lib/rss/maker/feed.rb, line 7
def initialize(feed_version="1.0")
  super
  @feed_type = "atom"
  @feed_subtype = "feed"
end


class RSS::Maker::Atom::Feed::Channel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Channel

In Files

  • lib/rss/maker/feed.rb

Parent

RSS::Maker::ChannelBase

Included Modules

  • RSS::Maker::SetupDefaultLanguage

Public Instance Methods

have_required_values?() click to toggle source
# File lib/rss/maker/feed.rb, line 44
def have_required_values?
  super and
    (!authors.empty? or
     @maker.items.any? {|item| !item.authors.empty?})
end
to_feed(feed) click to toggle source
# File lib/rss/maker/feed.rb, line 27
def to_feed(feed)
  set_default_values do
    setup_values(feed)
    feed.dc_dates.clear
    setup_other_elements(feed)
    if image_favicon.about
      icon = feed.class::Icon.new
      icon.content = image_favicon.about
      feed.icon = icon
    end
    unless have_required_values?
      raise NotSetError.new("maker.channel",
                            not_set_required_variables)
    end
  end
end


class RSS::Maker::Atom::Feed::Channel::Categories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Channel::Categories

In Files

  • lib/rss/maker/feed.rb

Parent

CategoriesBase


class RSS::Maker::Atom::Feed::Channel::Categories::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Channel::Categories::Category

In Files

  • lib/rss/maker/feed.rb

Parent

CategoryBase

Included Modules

  • RSS::Maker::AtomCategory

Public Class Methods

not_set_name() click to toggle source
# File lib/rss/maker/feed.rb, line 108
def self.not_set_name
  "maker.channel.category"
end


class RSS::Maker::Atom::Feed::Channel::Cloud - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Channel::Cloud

In Files

  • lib/rss/maker/feed.rb

Parent

CloudBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/feed.rb, line 100
def to_feed(*args)
end


class RSS::Maker::Atom::Feed::Channel::Generator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Channel::Generator

In Files

  • lib/rss/maker/feed.rb

Parent

GeneratorBase

Included Modules

  • RSS::Maker::AtomGenerator

Public Class Methods

not_set_name() click to toggle source
# File lib/rss/maker/feed.rb, line 131
def self.not_set_name
  "maker.channel.generator"
end


class RSS::Maker::Atom::Feed::Channel::Links - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Channel::Links

In Files

  • lib/rss/maker/feed.rb

Parent

LinksBase


class RSS::Maker::Atom::Feed::Channel::Links::Link - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Channel::Links::Link

In Files

  • lib/rss/maker/feed.rb

Parent

LinkBase

Included Modules

  • RSS::Maker::AtomLink

Public Class Methods

not_set_name() click to toggle source
# File lib/rss/maker/feed.rb, line 118
def self.not_set_name
  "maker.channel.link"
end


class RSS::Maker::Atom::Feed::Channel::SkipDays - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Channel::SkipDays

In Files

  • lib/rss/maker/feed.rb

Parent

SkipDaysBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/feed.rb, line 84
def to_feed(*args)
end


class RSS::Maker::Atom::Feed::Channel::SkipDays::Day - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Channel::SkipDays::Day

In Files

  • lib/rss/maker/feed.rb

Parent

DayBase


class RSS::Maker::Atom::Feed::Channel::SkipHours - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Channel::SkipHours

In Files

  • lib/rss/maker/feed.rb

Parent

SkipHoursBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/feed.rb, line 92
def to_feed(*args)
end


class RSS::Maker::Atom::Feed::Channel::SkipHours::Hour - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Channel::SkipHours::Hour

In Files

  • lib/rss/maker/feed.rb

Parent

HourBase


class RSS::Maker::Atom::Feed::Image - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Image

In Files

  • lib/rss/maker/feed.rb

Parent

RSS::Maker::ImageBase

Public Instance Methods

to_feed(feed) click to toggle source
# File lib/rss/maker/feed.rb, line 147
def to_feed(feed)
  logo = feed.class::Logo.new
  class << logo
    alias_method(:url=, :content=)
  end
  set = setup_values(logo)
  class << logo
    remove_method(:url=)
  end
  if set
    feed.logo = logo
    set_parent(logo, feed)
    setup_other_elements(feed, logo)
  elsif variable_is_set?
    raise NotSetError.new("maker.image", not_set_required_variables)
  end
end


class RSS::Maker::Atom::Feed::Items - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items

In Files

  • lib/rss/maker/feed.rb

Parent

RSS::Maker::ItemsBase

Public Instance Methods

to_feed(feed) click to toggle source
# File lib/rss/maker/feed.rb, line 172
def to_feed(feed)
  normalize.each do |item|
    item.to_feed(feed)
  end
  setup_other_elements(feed, feed.entries)
end


class RSS::Maker::Atom::Feed::Items::Item - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item

In Files

  • lib/rss/maker/feed.rb

Parent

ItemBase

Public Instance Methods

have_required_values?() click to toggle source
# File lib/rss/maker/feed.rb, line 195
def have_required_values?
  set_default_values do
    super and title {|t| t.have_required_values?}
  end
end
to_feed(feed) click to toggle source
# File lib/rss/maker/feed.rb, line 180
def to_feed(feed)
  set_default_values do
    entry = feed.class::Entry.new
    set = setup_values(entry)
    entry.dc_dates.clear
    setup_other_elements(feed, entry)
    if set
      feed.entries << entry
      set_parent(entry, feed)
    elsif variable_is_set?
      raise NotSetError.new("maker.item", not_set_required_variables)
    end
  end
end


class RSS::Maker::Atom::Feed::Items::Item::Categories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Categories

In Files

  • lib/rss/maker/feed.rb

Parent

CategoriesBase


class RSS::Maker::Atom::Feed::Items::Item::Categories::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Categories::Category

In Files

  • lib/rss/maker/feed.rb

Parent

CategoryBase

Included Modules

  • RSS::Maker::AtomCategory

Public Class Methods

not_set_name() click to toggle source
# File lib/rss/maker/feed.rb, line 338
def self.not_set_name
  "maker.item.category"
end


class RSS::Maker::Atom::Feed::Items::Item::Content - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Content

In Files

  • lib/rss/maker/feed.rb

Parent

ContentBase

Public Instance Methods

to_feed(feed, current) click to toggle source
# File lib/rss/maker/feed.rb, line 367
def to_feed(feed, current)
  content = current.class::Content.new
  if setup_values(content)
    content.src = nil if content.src and content.content
    current.content = content
    set_parent(content, current)
    setup_other_elements(feed, content)
  elsif variable_is_set?
    raise NotSetError.new("maker.item.content",
                          not_set_required_variables)
  end
end


class RSS::Maker::Atom::Feed::Items::Item::Enclosure - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Enclosure

In Files

  • lib/rss/maker/feed.rb

Parent

EnclosureBase

Public Instance Methods

to_feed(feed, current) click to toggle source
# File lib/rss/maker/feed.rb, line 232
def to_feed(feed, current)
end


class RSS::Maker::Atom::Feed::Items::Item::Guid - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Guid

In Files

  • lib/rss/maker/feed.rb

Parent

GuidBase

Public Instance Methods

to_feed(feed, current) click to toggle source
# File lib/rss/maker/feed.rb, line 227
def to_feed(feed, current)
end


class RSS::Maker::Atom::Feed::Items::Item::Links - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Links

In Files

  • lib/rss/maker/feed.rb

Parent

LinksBase


class RSS::Maker::Atom::Feed::Items::Item::Links::Link - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Links::Link

In Files

  • lib/rss/maker/feed.rb

Parent

LinkBase

Included Modules

  • RSS::Maker::AtomLink

Public Class Methods

not_set_name() click to toggle source
# File lib/rss/maker/feed.rb, line 352
def self.not_set_name
  "maker.item.link"
end


class RSS::Maker::Atom::Feed::Items::Item::Source - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Source

In Files

  • lib/rss/maker/feed.rb

Parent

SourceBase

Public Instance Methods

to_feed(feed, current) click to toggle source
# File lib/rss/maker/feed.rb, line 237
def to_feed(feed, current)
  source = current.class::Source.new
  setup_values(source)
  current.source = source
  set_parent(source, current)
  setup_other_elements(feed, source)
  current.source = nil if source.to_s == "<source/>"
end


class RSS::Maker::Atom::Feed::Items::Item::Source::Categories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Source::Categories

In Files

  • lib/rss/maker/feed.rb

Parent

CategoriesBase


class RSS::Maker::Atom::Feed::Items::Item::Source::Categories::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Source::Categories::Category

In Files

  • lib/rss/maker/feed.rb

Parent

CategoryBase

Included Modules

  • RSS::Maker::AtomCategory

Public Class Methods

not_set_name() click to toggle source
# File lib/rss/maker/feed.rb, line 264
def self.not_set_name
  "maker.item.source.category"
end


class RSS::Maker::Atom::Feed::Items::Item::Source::Generator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Source::Generator

In Files

  • lib/rss/maker/feed.rb

Parent

GeneratorBase

Included Modules

  • RSS::Maker::AtomGenerator

Public Class Methods

not_set_name() click to toggle source
# File lib/rss/maker/feed.rb, line 273
def self.not_set_name
  "maker.item.source.generator"
end


class RSS::Maker::Atom::Feed::Items::Item::Source::Icon - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Source::Icon

In Files

  • lib/rss/maker/feed.rb

Parent

IconBase

Public Instance Methods

to_feed(feed, current) click to toggle source
# File lib/rss/maker/feed.rb, line 279
def to_feed(feed, current)
  icon = current.class::Icon.new
  class << icon
    alias_method(:url=, :content=)
  end
  set = setup_values(icon)
  class << icon
    remove_method(:url=)
  end
  if set
    current.icon = icon
    set_parent(icon, current)
    setup_other_elements(feed, icon)
  elsif variable_is_set?
    raise NotSetError.new("maker.item.source.icon",
                          not_set_required_variables)
  end
end


class RSS::Maker::Atom::Feed::Items::Item::Source::Links - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Source::Links

In Files

  • lib/rss/maker/feed.rb

Parent

LinksBase


class RSS::Maker::Atom::Feed::Items::Item::Source::Links::Link - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Source::Links::Link

In Files

  • lib/rss/maker/feed.rb

Parent

LinkBase

Included Modules

  • RSS::Maker::AtomLink

Public Class Methods

not_set_name() click to toggle source
# File lib/rss/maker/feed.rb, line 308
def self.not_set_name
  "maker.item.source.link"
end


class RSS::Maker::Atom::Feed::Items::Item::Source::Logo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Items::Item::Source::Logo

In Files

  • lib/rss/maker/feed.rb

Parent

LogoBase

Included Modules

  • RSS::Maker::AtomLogo

Public Class Methods

not_set_name() click to toggle source
# File lib/rss/maker/feed.rb, line 317
def self.not_set_name
  "maker.item.source.logo"
end


class RSS::Maker::Atom::Feed::Textinput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Atom::Feed::Textinput

In Files

  • lib/rss/maker/feed.rb

Parent

RSS::Maker::TextinputBase


module RSS::Maker::AtomCategory - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::AtomCategory

In Files

  • lib/rss/maker/atom.rb

Public Instance Methods

to_feed(feed, current) click to toggle source
# File lib/rss/maker/atom.rb, line 84
def to_feed(feed, current)
  category = feed.class::Category.new
  set = setup_values(category)
  if set
    current.categories << category
    set_parent(category, current)
    setup_other_elements(feed)
  else
    raise NotSetError.new(self.class.not_set_name,
                          not_set_required_variables)
  end
end


module RSS::Maker::AtomGenerator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::AtomGenerator

In Files

  • lib/rss/maker/atom.rb

Public Instance Methods

to_feed(feed, current) click to toggle source
# File lib/rss/maker/atom.rb, line 128
def to_feed(feed, current)
  generator = current.class::Generator.new
  if setup_values(generator)
    current.generator = generator
    set_parent(generator, current)
    setup_other_elements(feed)
  elsif variable_is_set?
    raise NotSetError.new(self.class.not_set_name,
                          not_set_required_variables)
  end
end


module RSS::Maker::AtomLink - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::AtomLink

In Files

  • lib/rss/maker/atom.rb

Public Instance Methods

to_feed(feed, current) click to toggle source
# File lib/rss/maker/atom.rb, line 108
def to_feed(feed, current)
  link = feed.class::Link.new
  set = setup_values(link)
  if set
    current.links << link
    set_parent(link, current)
    setup_other_elements(feed)
  else
    raise NotSetError.new(self.class.not_set_name,
                          not_set_required_variables)
  end
end


module RSS::Maker::AtomLogo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::AtomLogo

In Files

  • lib/rss/maker/atom.rb

Public Instance Methods

to_feed(feed, current) click to toggle source
# File lib/rss/maker/atom.rb, line 147
def to_feed(feed, current)
  logo = current.class::Logo.new
  class << logo
    alias_method(:uri=, :content=)
  end
  set = setup_values(logo)
  class << logo
    remove_method(:uri=)
  end
  if set
    current.logo = logo
    set_parent(logo, current)
    setup_other_elements(feed)
  elsif variable_is_set?
    raise NotSetError.new(self.class.not_set_name,
                          not_set_required_variables)
  end
end


module RSS::Maker::AtomPersonConstructBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::AtomPersonConstructBase

In Files

  • lib/rss/maker/base.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/base.rb, line 279
      def self.append_features(klass)
        super

        klass.class_eval("          %w(name uri email).each do |element|
            attr_accessor element
            add_need_initialize_variable(element)
          end
", __FILE__, __LINE__ + 1)
      end


module RSS::Maker::AtomPersons - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::AtomPersons

In Files

  • lib/rss/maker/atom.rb

Public Instance Methods

def_atom_persons(klass, name, maker_name, plural=nil) click to toggle source
# File lib/rss/maker/atom.rb, line 9
      def def_atom_persons(klass, name, maker_name, plural=nil)
        plural ||= "#{name}s"
        klass_name = Utils.to_class_name(name)
        plural_klass_name = Utils.to_class_name(plural)

        klass.class_eval("          class #{plural_klass_name} < #{plural_klass_name}Base
            class #{klass_name} < #{klass_name}Base
              def to_feed(feed, current)
                #{name} = feed.class::#{klass_name}.new
                set = setup_values(#{name})
                unless set
                  raise NotSetError.new(#{maker_name.dump},
                                        not_set_required_variables)
                end
                current.#{plural} << #{name}
                set_parent(#{name}, current)
                setup_other_elements(#{name})
              end

              private
              def required_variable_names
                %w(name)
              end
            end
          end
", __FILE__, __LINE__ + 1)
      end


module RSS::Maker::AtomTextConstruct - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::AtomTextConstruct

In Files

  • lib/rss/maker/atom.rb

Public Class Methods

def_atom_text_construct(klass, name, maker_name, klass_name=nil, atom_klass_name=nil) click to toggle source
# File lib/rss/maker/atom.rb, line 41
        def def_atom_text_construct(klass, name, maker_name, klass_name=nil,
                                    atom_klass_name=nil)
          klass_name ||= Utils.to_class_name(name)
          atom_klass_name ||= Utils.to_class_name(name)

          klass.class_eval("            class #{klass_name} < #{klass_name}Base
              include #{self.name}
              def to_feed(feed, current)
                #{name} = current.class::#{atom_klass_name}.new
                if setup_values(#{name})
                  current.#{name} = #{name}
                  set_parent(#{name}, current)
                  setup_other_elements(feed)
                elsif variable_is_set?
                  raise NotSetError.new(#{maker_name.dump},
                                        not_set_required_variables)
                end
              end
            end
", __FILE__, __LINE__ + 1)
        end


module RSS::Maker::AtomTextConstructBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::AtomTextConstructBase

In Files

  • lib/rss/maker/base.rb

Included Modules

  • RSS::Maker::AtomTextConstructBase::EnsureXMLContent

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/base.rb, line 345
def self.append_features(klass)
  super

  klass.class_eval do
    include EnsureXMLContent
  end
end


module RSS::Maker::AtomTextConstructBase::EnsureXMLContent - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::AtomTextConstructBase::EnsureXMLContent

In Files

  • lib/rss/maker/base.rb

Public Class Methods

included(base) click to toggle source
# File lib/rss/maker/base.rb, line 294
def included(base)
  super
  base.class_eval do
    %w(type content xml_content).each do |element|
      attr_reader element
      attr_writer element if element != "xml_content"
      add_need_initialize_variable(element)
    end

    alias_method(:xhtml, :xml_content)
  end
end

Public Instance Methods

ensure_xml_content(content) click to toggle source
# File lib/rss/maker/base.rb, line 308
def ensure_xml_content(content)
  xhtml_uri = ::RSS::Atom::XHTML_URI
  unless content.is_a?(RSS::XML::Element) and
      ["div", xhtml_uri] == [content.name, content.uri]
    children = content
    children = [children] unless content.is_a?(Array)
    children = set_xhtml_uri_as_default_uri(children)
    content = RSS::XML::Element.new("div", nil, xhtml_uri,
                                    {"xmlns" => xhtml_uri},
                                    children)
  end
  content
end
xhtml=(content) click to toggle source
# File lib/rss/maker/base.rb, line 326
def xhtml=(content)
  self.xml_content = content
end
xml_content=(content) click to toggle source
# File lib/rss/maker/base.rb, line 322
def xml_content=(content)
  @xml_content = ensure_xml_content(content)
end


class RSS::Maker::Base - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::Base

In Files

  • lib/rss/maker/base.rb

Parent

Object

Included Modules

  • Enumerable

Constants

NEED_INITIALIZE_VARIABLES
OTHER_ELEMENTS

Attributes

maker[R]

Public Class Methods

add_need_initialize_variable(variable_name, init_value=nil, &init_block) click to toggle source
# File lib/rss/maker/base.rb, line 34
def add_need_initialize_variable(variable_name, init_value=nil,
                                 &init_block)
  init_value ||= init_block
  self::NEED_INITIALIZE_VARIABLES << [variable_name, init_value]
end
add_other_element(variable_name) click to toggle source
# File lib/rss/maker/base.rb, line 30
def add_other_element(variable_name)
  self::OTHER_ELEMENTS << variable_name
end
def_array_element(name, plural=nil, klass_name=nil) click to toggle source
# File lib/rss/maker/base.rb, line 40
        def def_array_element(name, plural=nil, klass_name=nil)
          include Enumerable
          extend Forwardable

          plural ||= "#{name}s"
          klass_name ||= Utils.to_class_name(name)
          def_delegators("@#{plural}", :<<, :[], :[]=, :first, :last)
          def_delegators("@#{plural}", :push, :pop, :shift, :unshift)
          def_delegators("@#{plural}", :each, :size, :empty?, :clear)

          add_need_initialize_variable(plural) {[]}

          module_eval("            def new_#{name}
              #{name} = self.class::#{klass_name}.new(@maker)
              @#{plural} << #{name}
              if block_given?
                yield #{name}
              else
                #{name}
              end
            end
            alias new_child new_#{name}

            def to_feed(*args)
              @#{plural}.each do |#{name}|
                #{name}.to_feed(*args)
              end
            end

            def replace(elements)
              @#{plural}.replace(elements.to_a)
            end
", __FILE__, __LINE__ + 1)
        end
def_classed_element(name, class_name=nil, attribute_name=nil) click to toggle source
# File lib/rss/maker/base.rb, line 94
        def def_classed_element(name, class_name=nil, attribute_name=nil)
          def_classed_element_without_accessor(name, class_name)
          if attribute_name
            module_eval("              def #{name}
                if block_given?
                  yield(@#{name})
                else
                  @#{name}.#{attribute_name}
                end
              end

              def #{name}=(new_value)
                @#{name}.#{attribute_name} = new_value
              end
", __FILE__, __LINE__ + 1)
          else
            attr_reader name
          end
        end
def_classed_element_without_accessor(name, class_name=nil) click to toggle source
# File lib/rss/maker/base.rb, line 76
        def def_classed_element_without_accessor(name, class_name=nil)
          class_name ||= Utils.to_class_name(name)
          add_other_element(name)
          add_need_initialize_variable(name) do |object|
            object.send("make_#{name}")
          end
          module_eval("            private
            def setup_#{name}(feed, current)
              @#{name}.to_feed(feed, current)
            end

            def make_#{name}
              self.class::#{class_name}.new(@maker)
            end
", __FILE__, __LINE__ + 1)
        end
def_classed_elements(name, attribute, plural_class_name=nil, plural_name=nil, new_name=nil) { |local_variable_name, new_value_variable_name| ... } click to toggle source
# File lib/rss/maker/base.rb, line 115
        def def_classed_elements(name, attribute, plural_class_name=nil,
                                 plural_name=nil, new_name=nil)
          plural_name ||= "#{name}s"
          new_name ||= name
          def_classed_element(plural_name, plural_class_name)
          local_variable_name = "_#{name}"
          new_value_variable_name = "new_value"
          additional_setup_code = nil
          if block_given?
            additional_setup_code = yield(local_variable_name,
                                          new_value_variable_name)
          end
          module_eval("            def #{name}
              #{local_variable_name} = #{plural_name}.first
              #{local_variable_name} ? #{local_variable_name}.#{attribute} : nil
            end

            def #{name}=(#{new_value_variable_name})
              #{local_variable_name} =
                #{plural_name}.first || #{plural_name}.new_#{new_name}
              #{additional_setup_code}
              #{local_variable_name}.#{attribute} = #{new_value_variable_name}
            end
", __FILE__, __LINE__ + 1)
        end
def_csv_element(name, type=nil) click to toggle source
# File lib/rss/maker/base.rb, line 159
        def def_csv_element(name, type=nil)
          def_other_element_without_accessor(name)
          attr_reader(name)
          converter = ""
          if type == :integer
            converter = "{|v| Integer(v)}"
          end
          module_eval("            def #{name}=(value)
              @#{name} = Utils::CSV.parse(value)#{converter}
            end
", __FILE__, __LINE__ + 1)
        end
def_other_element(name) click to toggle source
# File lib/rss/maker/base.rb, line 142
def def_other_element(name)
  attr_accessor name
  def_other_element_without_accessor(name)
end
def_other_element_without_accessor(name) click to toggle source
# File lib/rss/maker/base.rb, line 147
        def def_other_element_without_accessor(name)
          add_need_initialize_variable(name)
          add_other_element(name)
          module_eval("            def setup_#{name}(feed, current)
              if !@#{name}.nil? and current.respond_to?(:#{name}=)
                current.#{name} = @#{name}
              end
            end
", __FILE__, __LINE__ + 1)
        end
inherited(subclass) click to toggle source
# File lib/rss/maker/base.rb, line 25
def inherited(subclass)
  subclass.const_set(:OTHER_ELEMENTS, [])
  subclass.const_set(:NEED_INITIALIZE_VARIABLES, [])
end
inherited_base() click to toggle source
# File lib/rss/maker/base.rb, line 21
def inherited_base
  ::RSS::Maker::Base
end
need_initialize_variables() click to toggle source
# File lib/rss/maker/base.rb, line 17
def need_initialize_variables
  inherited_array_reader("NEED_INITIALIZE_VARIABLES")
end
new(maker) click to toggle source
# File lib/rss/maker/base.rb, line 175
def initialize(maker)
  @maker = maker
  @default_values_are_set = false
  initialize_variables
end
other_elements() click to toggle source
# File lib/rss/maker/base.rb, line 14
def other_elements
  inherited_array_reader("OTHER_ELEMENTS")
end

Public Instance Methods

have_required_values?() click to toggle source
# File lib/rss/maker/base.rb, line 181
def have_required_values?
  not_set_required_variables.empty?
end
variable_is_set?() click to toggle source
# File lib/rss/maker/base.rb, line 185
def variable_is_set?
  variables.any? {|var| not __send__(var).nil?}
end


class RSS::Maker::ChannelBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase

In Files

  • lib/rss/maker/base.rb
  • lib/rss/maker/dublincore.rb
  • lib/rss/maker/image.rb
  • lib/rss/maker/itunes.rb
  • lib/rss/maker/syndication.rb
  • lib/rss/maker/taxonomy.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::SetupDefaultDate
  • RSS::Maker::DublinCoreModel
  • RSS::Maker::ImageFaviconModel
  • RSS::Maker::ITunesChannelModel
  • RSS::Maker::SyndicationModel
  • RSS::Maker::TaxonomyTopicsModel

Public Instance Methods

date=(_date) click to toggle source
# File lib/rss/maker/base.rb, line 521
def date=(_date)
  @date = _parse_date_if_needed(_date)
end
icon() click to toggle source
# File lib/rss/maker/base.rb, line 551
def icon
  image_favicon.about
end
icon=(url) click to toggle source
# File lib/rss/maker/base.rb, line 555
def icon=(url)
  image_favicon.about = url
end
lastBuildDate=(_date) click to toggle source
# File lib/rss/maker/base.rb, line 525
def lastBuildDate=(_date)
  @lastBuildDate = _parse_date_if_needed(_date)
end
logo() click to toggle source
# File lib/rss/maker/base.rb, line 559
def logo
  maker.image.url
end
logo=(url) click to toggle source
# File lib/rss/maker/base.rb, line 563
def logo=(url)
  maker.image.url = url
end
pubDate() click to toggle source
# File lib/rss/maker/base.rb, line 529
def pubDate
  date
end
pubDate=(date) click to toggle source
# File lib/rss/maker/base.rb, line 533
def pubDate=(date)
  self.date = date
end
updated() click to toggle source
# File lib/rss/maker/base.rb, line 537
def updated
  date
end
updated=(date) click to toggle source
# File lib/rss/maker/base.rb, line 541
def updated=(date)
  self.date = date
end


class RSS::Maker::ChannelBase::AuthorsBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::AuthorsBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::AuthorsBase::AuthorBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::AuthorsBase::AuthorBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomPersonConstructBase


class RSS::Maker::ChannelBase::CategoriesBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::CategoriesBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::CategoriesBase::CategoryBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::CategoriesBase::CategoryBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::CloudBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::CloudBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::ContributorsBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::ContributorsBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::ContributorsBase::ContributorBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::ContributorsBase::ContributorBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomPersonConstructBase


class RSS::Maker::ChannelBase::CopyrightBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::CopyrightBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomTextConstructBase


class RSS::Maker::ChannelBase::DescriptionBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::DescriptionBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomTextConstructBase


class RSS::Maker::ChannelBase::GeneratorBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::GeneratorBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::ITunesCategories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::ITunesCategories

In Files

  • lib/rss/maker/itunes.rb

Parent

ITunesCategoriesBase


class RSS::Maker::ChannelBase::ITunesCategories::ITunesCategory - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::ITunesCategories::ITunesCategory

In Files

  • lib/rss/maker/itunes.rb

Parent

ITunesCategoryBase

Constants

ITunesCategory


class RSS::Maker::ChannelBase::ITunesImage - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::ITunesImage

In Files

  • lib/rss/maker/itunes.rb

Parent

ITunesImageBase


class RSS::Maker::ChannelBase::ITunesOwner - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::ITunesOwner

In Files

  • lib/rss/maker/itunes.rb

Parent

ITunesOwnerBase


class RSS::Maker::ChannelBase::LinksBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::LinksBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::LinksBase::LinkBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::LinksBase::LinkBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::SkipDaysBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::SkipDaysBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::SkipDaysBase::DayBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::SkipDaysBase::DayBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::SkipHoursBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::SkipHoursBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::SkipHoursBase::HourBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::SkipHoursBase::HourBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ChannelBase::TitleBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ChannelBase::TitleBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomTextConstructBase


module RSS::Maker::ContentModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::ContentModel

In Files

  • lib/rss/maker/content.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/content.rb, line 8
def self.append_features(klass)
  super

  ::RSS::ContentModel::ELEMENTS.each do |name|
    klass.def_other_element(name)
  end
end


module RSS::Maker::DublinCoreModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::DublinCoreModel

In Files

  • lib/rss/maker/dublincore.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/dublincore.rb, line 7
      def self.append_features(klass)
        super

        ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
          plural_name ||= "#{name}s"
          full_name = "#{RSS::DC_PREFIX}_#{name}"
          full_plural_name = "#{RSS::DC_PREFIX}_#{plural_name}"
          plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
          klass.def_classed_elements(full_name, "value", plural_klass_name,
                                     full_plural_name, name)
          klass.module_eval("            def new_#{full_name}(value=nil)
              _#{full_name} = #{full_plural_name}.new_#{name}
              _#{full_name}.value = value
              if block_given?
                yield _#{full_name}
              else
                _#{full_name}
              end
            end
", __FILE__, __LINE__ + 1)
        end

        klass.module_eval("          # For backward compatibility
          alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list
", __FILE__, __LINE__ + 1)
      end
install_dublin_core(klass) click to toggle source
# File lib/rss/maker/dublincore.rb, line 70
      def self.install_dublin_core(klass)
        ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
          plural_name ||= "#{name}s"
          klass_name = Utils.to_class_name(name)
          full_klass_name = "DublinCore#{klass_name}"
          plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
          klass.module_eval("          class #{plural_klass_name} < #{plural_klass_name}Base
            class #{full_klass_name} < #{full_klass_name}Base
            end
            #{klass_name} = #{full_klass_name}
          end
", __FILE__, __LINE__ + 1)
        end
      end


module RSS::Maker::ITunesBaseModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::ITunesBaseModel

In Files

  • lib/rss/maker/itunes.rb

Public Instance Methods

def_class_accessor(klass, name, type, *args) click to toggle source
# File lib/rss/maker/itunes.rb, line 7
def def_class_accessor(klass, name, type, *args)
  name = name.gsub(/-/, "_").gsub(/^itunes_/, '')
  full_name = "#{RSS::ITUNES_PREFIX}_#{name}"
  case type
  when nil
    klass.def_other_element(full_name)
  when :yes_other
    def_yes_other_accessor(klass, full_name)
  when :yes_clean_other
    def_yes_clean_other_accessor(klass, full_name)
  when :csv
    def_csv_accessor(klass, full_name)
  when :element, :attribute
    recommended_attribute_name, = *args
    klass_name = "ITunes#{Utils.to_class_name(name)}"
    klass.def_classed_element(full_name, klass_name,
                              recommended_attribute_name)
  when :elements
    plural_name, recommended_attribute_name = args
    plural_name ||= "#{name}s"
    full_plural_name = "#{RSS::ITUNES_PREFIX}_#{plural_name}"
    klass_name = "ITunes#{Utils.to_class_name(name)}"
    plural_klass_name = "ITunes#{Utils.to_class_name(plural_name)}"
    def_elements_class_accessor(klass, name, full_name, full_plural_name,
                                klass_name, plural_klass_name,
                                recommended_attribute_name)
  end
end
def_csv_accessor(klass, full_name) click to toggle source
# File lib/rss/maker/itunes.rb, line 54
def def_csv_accessor(klass, full_name)
  klass.def_csv_element(full_name)
end
def_elements_class_accessor(klass, name, full_name, full_plural_name, klass_name, plural_klass_name, recommended_attribute_name=nil) click to toggle source
# File lib/rss/maker/itunes.rb, line 58
      def def_elements_class_accessor(klass, name, full_name, full_plural_name,
                                      klass_name, plural_klass_name,
                                      recommended_attribute_name=nil)
        if recommended_attribute_name
          klass.def_classed_elements(full_name, recommended_attribute_name,
                                     plural_klass_name, full_plural_name)
        else
          klass.def_classed_element(full_plural_name, plural_klass_name)
        end
        klass.module_eval("          def new_#{full_name}(text=nil)
            #{full_name} = @#{full_plural_name}.new_#{name}
            #{full_name}.text = text
            if block_given?
              yield #{full_name}
            else
              #{full_name}
            end
          end
", __FILE__, __LINE__ + 1)
      end
def_yes_clean_other_accessor(klass, full_name) click to toggle source
# File lib/rss/maker/itunes.rb, line 45
      def def_yes_clean_other_accessor(klass, full_name)
        klass.def_other_element(full_name)
        klass.module_eval("          def #{full_name}?
            Utils::YesCleanOther.parse(#{full_name})
          end
", __FILE__, __LINE__ + 1)
      end
def_yes_other_accessor(klass, full_name) click to toggle source
# File lib/rss/maker/itunes.rb, line 36
      def def_yes_other_accessor(klass, full_name)
        klass.def_other_element(full_name)
        klass.module_eval("          def #{full_name}?
            Utils::YesOther.parse(@#{full_name})
          end
", __FILE__, __LINE__ + 1)
      end


module RSS::Maker::ITunesChannelModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::ITunesChannelModel

In Files

  • lib/rss/maker/itunes.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/itunes.rb, line 85
def append_features(klass)
  super

  ::RSS::ITunesChannelModel::ELEMENT_INFOS.each do |name, type, *args|
    def_class_accessor(klass, name, type, *args)
  end
end


class RSS::Maker::ITunesChannelModel::ITunesCategoriesBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ITunesChannelModel::ITunesCategoriesBase

In Files

  • lib/rss/maker/itunes.rb

Parent

RSS::Maker::Base


class RSS::Maker::ITunesChannelModel::ITunesCategoriesBase::ITunesCategoryBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ITunesChannelModel::ITunesCategoriesBase::ITunesCategoryBase

In Files

  • lib/rss/maker/itunes.rb

Parent

RSS::Maker::Base

Attributes

text[RW]

Public Instance Methods

have_required_values?() click to toggle source
# File lib/rss/maker/itunes.rb, line 103
def have_required_values?
  text
end
to_feed(feed, current) click to toggle source
# File lib/rss/maker/itunes.rb, line 108
def to_feed(feed, current)
  if text and current.respond_to?(:itunes_category)
    new_item = current.class::ITunesCategory.new(text)
    to_feed_for_categories(feed, new_item)
    current.itunes_categories << new_item
  end
end
Also aliased as: to_feed_for_categories
to_feed_for_categories(feed, current) click to toggle source
Alias for: to_feed


class RSS::Maker::ITunesChannelModel::ITunesImageBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ITunesChannelModel::ITunesImageBase

In Files

  • lib/rss/maker/itunes.rb

Parent

RSS::Maker::Base

Attributes

href[RW]

Public Instance Methods

to_feed(feed, current) click to toggle source
# File lib/rss/maker/itunes.rb, line 122
def to_feed(feed, current)
  if @href and current.respond_to?(:itunes_image)
    current.itunes_image ||= current.class::ITunesImage.new
    current.itunes_image.href = @href
  end
end


class RSS::Maker::ITunesChannelModel::ITunesOwnerBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ITunesChannelModel::ITunesOwnerBase

In Files

  • lib/rss/maker/itunes.rb

Parent

RSS::Maker::Base

Public Instance Methods

to_feed(feed, current) click to toggle source
# File lib/rss/maker/itunes.rb, line 136
def to_feed(feed, current)
  if current.respond_to?(:itunes_owner=)
    _not_set_required_variables = not_set_required_variables
    if (required_variable_names - _not_set_required_variables).empty?
      return
    end

    unless have_required_values?
      raise NotSetError.new("maker.channel.itunes_owner",
                            _not_set_required_variables)
    end
    current.itunes_owner ||= current.class::ITunesOwner.new
    current.itunes_owner.itunes_name = @itunes_name
    current.itunes_owner.itunes_email = @itunes_email
  end
end


module RSS::Maker::ITunesItemModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::ITunesItemModel

In Files

  • lib/rss/maker/itunes.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/itunes.rb, line 164
def append_features(klass)
  super

  ::RSS::ITunesItemModel::ELEMENT_INFOS.each do |name, type, *args|
    def_class_accessor(klass, name, type, *args)
  end
end


class RSS::Maker::ITunesItemModel::ITunesDurationBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ITunesItemModel::ITunesDurationBase

In Files

  • lib/rss/maker/itunes.rb

Parent

RSS::Maker::Base

Attributes

content[R]

Public Instance Methods

content=(content) click to toggle source
# File lib/rss/maker/itunes.rb, line 182
def content=(content)
  if content.nil?
    @hour, @minute, @second, @content = nil
  else
    @hour, @minute, @second =
      ::RSS::ITunesItemModel::ITunesDuration.parse(content)
    @content = content
  end
end
hour=(hour) click to toggle source
# File lib/rss/maker/itunes.rb, line 192
def hour=(hour)
  @hour = Integer(hour)
  update_content
end
minute=(minute) click to toggle source
# File lib/rss/maker/itunes.rb, line 197
def minute=(minute)
  @minute = Integer(minute)
  update_content
end
second=(second) click to toggle source
# File lib/rss/maker/itunes.rb, line 202
def second=(second)
  @second = Integer(second)
  update_content
end
to_feed(feed, current) click to toggle source
# File lib/rss/maker/itunes.rb, line 207
def to_feed(feed, current)
  if @content and current.respond_to?(:itunes_duration=)
    current.itunes_duration ||= current.class::ITunesDuration.new
    current.itunes_duration.content = @content
  end
end


class RSS::Maker::ImageBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ImageBase

In Files

  • lib/rss/maker/base.rb
  • lib/rss/maker/dublincore.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::DublinCoreModel

Public Instance Methods

link() click to toggle source
# File lib/rss/maker/base.rb, line 665
def link
  @maker.channel.link
end


module RSS::Maker::ImageFaviconModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::ImageFaviconModel

In Files

  • lib/rss/maker/image.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/image.rb, line 52
def self.append_features(klass)
  super

  name = "#{RSS::IMAGE_PREFIX}_favicon"
  klass.def_classed_element(name)
end
install_image_favicon(klass) click to toggle source
# File lib/rss/maker/image.rb, line 59
      def self.install_image_favicon(klass)
        klass.module_eval("          class ImageFavicon < ImageFaviconBase
            DublinCoreModel.install_dublin_core(self)
          end
", __FILE__, __LINE__ + 1)
      end


class RSS::Maker::ImageFaviconModel::ImageFaviconBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ImageFaviconModel::ImageFaviconBase

In Files

  • lib/rss/maker/image.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::DublinCoreModel

Attributes

about[RW]
image_size[RW]
size[RW]
size=[RW]

Public Instance Methods

have_required_values?() click to toggle source
# File lib/rss/maker/image.rb, line 76
def have_required_values?
  @about and @image_size
end
to_feed(feed, current) click to toggle source
# File lib/rss/maker/image.rb, line 80
def to_feed(feed, current)
  if current.respond_to?(:image_favicon=) and have_required_values?
    favicon = current.class::ImageFavicon.new
    setup_values(favicon)
    setup_other_elements(favicon)
    current.image_favicon = favicon
  end
end


module RSS::Maker::ImageItemModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::ImageItemModel

In Files

  • lib/rss/maker/image.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/image.rb, line 8
def self.append_features(klass)
  super

  name = "#{RSS::IMAGE_PREFIX}_item"
  klass.def_classed_element(name)
end
install_image_item(klass) click to toggle source
# File lib/rss/maker/image.rb, line 15
      def self.install_image_item(klass)
        klass.module_eval("          class ImageItem < ImageItemBase
            DublinCoreModel.install_dublin_core(self)
          end
", __FILE__, __LINE__ + 1)
      end


class RSS::Maker::ImageItemModel::ImageItemBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ImageItemModel::ImageItemBase

In Files

  • lib/rss/maker/image.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::DublinCoreModel

Attributes

about[RW]
height=[RW]
image_height[RW]
image_width[RW]
resource[RW]
width=[RW]

Public Instance Methods

have_required_values?() click to toggle source
# File lib/rss/maker/image.rb, line 36
def have_required_values?
  @about
end
to_feed(feed, current) click to toggle source
# File lib/rss/maker/image.rb, line 40
def to_feed(feed, current)
  if current.respond_to?(:image_item=) and have_required_values?
    item = current.class::ImageItem.new
    setup_values(item)
    setup_other_elements(item)
    current.image_item = item
  end
end


class RSS::Maker::ItemsBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase

In Files

  • lib/rss/maker/base.rb
  • lib/rss/maker/content.rb
  • lib/rss/maker/dublincore.rb
  • lib/rss/maker/image.rb
  • lib/rss/maker/itunes.rb
  • lib/rss/maker/slash.rb
  • lib/rss/maker/taxonomy.rb
  • lib/rss/maker/trackback.rb

Parent

RSS::Maker::Base

Attributes

do_sort[RW]
max_size[RW]

Public Class Methods

new(maker) click to toggle source
# File lib/rss/maker/base.rb, line 675
def initialize(maker)
  super
  @do_sort = false
  @max_size = -1
end

Public Instance Methods

normalize() click to toggle source
# File lib/rss/maker/base.rb, line 681
def normalize
  if @max_size >= 0
    sort_if_need[0...@max_size]
  else
    sort_if_need[0..@max_size]
  end
end


class RSS::Maker::ItemsBase::ItemBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase

In Files

  • lib/rss/maker/base.rb
  • lib/rss/maker/content.rb
  • lib/rss/maker/dublincore.rb
  • lib/rss/maker/image.rb
  • lib/rss/maker/itunes.rb
  • lib/rss/maker/slash.rb
  • lib/rss/maker/taxonomy.rb
  • lib/rss/maker/trackback.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::SetupDefaultDate
  • RSS::Maker::ContentModel
  • RSS::Maker::DublinCoreModel
  • RSS::Maker::ImageItemModel
  • RSS::Maker::ITunesItemModel
  • RSS::Maker::SlashModel
  • RSS::Maker::TaxonomyTopicsModel
  • RSS::Maker::TrackBackModel

Constants

AuthorsBase
CategoriesBase
ContributorsBase
LinksBase

Public Instance Methods

<=>(other) click to toggle source
# File lib/rss/maker/base.rb, line 756
def <=>(other)
  _date = date || dc_date
  _other_date = other.date || other.dc_date
  if _date and _other_date
    _date <=> _other_date
  elsif _date
    1
  elsif _other_date
    -1
  else
    0
  end
end
date=(_date) click to toggle source
# File lib/rss/maker/base.rb, line 733
def date=(_date)
  @date = _parse_date_if_needed(_date)
end
pubDate() click to toggle source
# File lib/rss/maker/base.rb, line 737
def pubDate
  date
end
pubDate=(date) click to toggle source
# File lib/rss/maker/base.rb, line 741
def pubDate=(date)
  self.date = date
end
updated() click to toggle source
# File lib/rss/maker/base.rb, line 745
def updated
  date
end
updated=(date) click to toggle source
# File lib/rss/maker/base.rb, line 749
def updated=(date)
  self.date = date
end


class RSS::Maker::ItemsBase::ItemBase::ContentBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::ContentBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomTextConstructBase::EnsureXMLContent

Public Instance Methods

inline_html?() click to toggle source
# File lib/rss/maker/base.rb, line 899
def inline_html?
  @type == "html"
end
inline_other?() click to toggle source
# File lib/rss/maker/base.rb, line 907
def inline_other?
  !out_of_line? and ![nil, "text", "html", "xhtml"].include?(@type)
end
inline_other_base64?() click to toggle source
# File lib/rss/maker/base.rb, line 921
def inline_other_base64?
  return false if @type.nil? or out_of_line?
  @type.include?("/") and !inline_other_text? and !inline_other_xml?
end
inline_other_text?() click to toggle source
# File lib/rss/maker/base.rb, line 911
def inline_other_text?
  return false if @type.nil? or out_of_line?
  /\Atext\//.match(@type) ? true : false
end
inline_other_xml?() click to toggle source
# File lib/rss/maker/base.rb, line 916
def inline_other_xml?
  return false if @type.nil? or out_of_line?
  /[\+\/]xml\z/.match(@type) ? true : false
end
inline_text?() click to toggle source
# File lib/rss/maker/base.rb, line 895
def inline_text?
  [nil, "text", "html"].include?(@type)
end
inline_xhtml?() click to toggle source
# File lib/rss/maker/base.rb, line 903
def inline_xhtml?
  @type == "xhtml"
end
out_of_line?() click to toggle source
# File lib/rss/maker/base.rb, line 926
def out_of_line?
  not @src.nil? and @content.nil?
end
xml=(content) click to toggle source
Alias for: xml_content=
xml_content=(content) click to toggle source
# File lib/rss/maker/base.rb, line 887
def xml_content=(content)
  content = ensure_xml_content(content) if inline_xhtml?
  @xml_content = content
end
Also aliased as: xml=


class RSS::Maker::ItemsBase::ItemBase::DescriptionBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::DescriptionBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomTextConstructBase


class RSS::Maker::ItemsBase::ItemBase::EnclosureBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::EnclosureBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ItemsBase::ItemBase::GuidBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::GuidBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Public Instance Methods

permanent_link=(bool) click to toggle source
# File lib/rss/maker/base.rb, line 780
def permanent_link=(bool)
  self.isPermaLink = bool
end
permanent_link?() click to toggle source
# File lib/rss/maker/base.rb, line 776
def permanent_link?
  isPermaLink
end


class RSS::Maker::ItemsBase::ItemBase::ITunesDuration - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::ITunesDuration

In Files

  • lib/rss/maker/itunes.rb

Parent

ITunesDurationBase


class RSS::Maker::ItemsBase::ItemBase::RightsBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::RightsBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomTextConstructBase


class RSS::Maker::ItemsBase::ItemBase::SourceBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::SourceBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::SetupDefaultDate

Constants

AuthorsBase
CategoriesBase
ContributorsBase
GeneratorBase
LinksBase

Public Instance Methods

date=(_date) click to toggle source
# File lib/rss/maker/base.rb, line 819
def date=(_date)
  @date = _parse_date_if_needed(_date)
end
updated() click to toggle source
# File lib/rss/maker/base.rb, line 823
def updated
  date
end
updated=(date) click to toggle source
# File lib/rss/maker/base.rb, line 827
def updated=(date)
  self.date = date
end


class RSS::Maker::ItemsBase::ItemBase::SourceBase::IconBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::SourceBase::IconBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ItemsBase::ItemBase::SourceBase::LogoBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::SourceBase::LogoBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::ItemsBase::ItemBase::SourceBase::RightsBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::SourceBase::RightsBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomTextConstructBase


class RSS::Maker::ItemsBase::ItemBase::SourceBase::SubtitleBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::SourceBase::SubtitleBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomTextConstructBase


class RSS::Maker::ItemsBase::ItemBase::SourceBase::TitleBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::SourceBase::TitleBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomTextConstructBase


class RSS::Maker::ItemsBase::ItemBase::TitleBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::ItemsBase::ItemBase::TitleBase

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::AtomTextConstructBase


class RSS::Maker::RSS09 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09

In Files

  • lib/rss/maker/0.9.rb

Parent

RSSBase

Public Class Methods

new(feed_version) click to toggle source
# File lib/rss/maker/0.9.rb, line 10
def initialize(feed_version)
  super
  @feed_type = "rss"
end


class RSS::Maker::RSS091 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS091

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09

Public Class Methods

new(feed_version="0.91") click to toggle source
# File lib/rss/maker/0.9.rb, line 462
def initialize(feed_version="0.91")
  super
end


class RSS::Maker::RSS091::Channel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS091::Channel

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09::Channel


class RSS::Maker::RSS091::Image - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS091::Image

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09::Image


class RSS::Maker::RSS091::Items - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS091::Items

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09::Items


class RSS::Maker::RSS091::Items::Item - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS091::Items::Item

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09::Items::Item


class RSS::Maker::RSS091::Textinput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS091::Textinput

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09::Textinput


class RSS::Maker::RSS092 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS092

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09

Public Class Methods

new(feed_version="0.92") click to toggle source
# File lib/rss/maker/0.9.rb, line 482
def initialize(feed_version="0.92")
  super
end


class RSS::Maker::RSS092::Channel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS092::Channel

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09::Channel


class RSS::Maker::RSS092::Image - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS092::Image

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09::Image


class RSS::Maker::RSS092::Items - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS092::Items

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09::Items


class RSS::Maker::RSS092::Items::Item - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS092::Items::Item

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09::Items::Item


class RSS::Maker::RSS092::Textinput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS092::Textinput

In Files

  • lib/rss/maker/0.9.rb

Parent

RSS::Maker::RSS09::Textinput


class RSS::Maker::RSS09::Channel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel

In Files

  • lib/rss/maker/0.9.rb

Parent

ChannelBase

Public Instance Methods

to_feed(rss) click to toggle source
# File lib/rss/maker/0.9.rb, line 25
def to_feed(rss)
  channel = Rss::Channel.new
  setup_values(channel)
  _not_set_required_variables = not_set_required_variables
  if _not_set_required_variables.empty?
    rss.channel = channel
    set_parent(channel, rss)
    setup_items(rss)
    setup_image(rss)
    setup_textinput(rss)
    setup_other_elements(rss, channel)
    rss
  else
    raise NotSetError.new("maker.channel", _not_set_required_variables)
  end
end


class RSS::Maker::RSS09::Channel::Authors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Authors

In Files

  • lib/rss/maker/0.9.rb

Parent

AuthorsBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/0.9.rb, line 167
def to_feed(rss, channel)
end


class RSS::Maker::RSS09::Channel::Authors::Author - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Authors::Author

In Files

  • lib/rss/maker/0.9.rb

Parent

AuthorBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/0.9.rb, line 171
def to_feed(rss, channel)
end


class RSS::Maker::RSS09::Channel::Categories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Categories

In Files

  • lib/rss/maker/0.9.rb

Parent

CategoriesBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 136
def to_feed(*args)
end


class RSS::Maker::RSS09::Channel::Categories::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Categories::Category

In Files

  • lib/rss/maker/0.9.rb

Parent

CategoryBase


class RSS::Maker::RSS09::Channel::Cloud - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Cloud

In Files

  • lib/rss/maker/0.9.rb

Parent

CloudBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 131
def to_feed(*args)
end


class RSS::Maker::RSS09::Channel::Contributors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Contributors

In Files

  • lib/rss/maker/0.9.rb

Parent

ContributorsBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/0.9.rb, line 177
def to_feed(rss, channel)
end


class RSS::Maker::RSS09::Channel::Contributors::Contributor - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Contributors::Contributor

In Files

  • lib/rss/maker/0.9.rb

Parent

ContributorBase


class RSS::Maker::RSS09::Channel::Copyright - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Copyright

In Files

  • lib/rss/maker/0.9.rb

Parent

CopyrightBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/0.9.rb, line 190
def to_feed(rss, channel)
  channel.copyright = content if have_required_values?
end


class RSS::Maker::RSS09::Channel::Description - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Description

In Files

  • lib/rss/maker/0.9.rb

Parent

DescriptionBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/0.9.rb, line 201
def to_feed(rss, channel)
  channel.description = content if have_required_values?
end


class RSS::Maker::RSS09::Channel::Generator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Generator

In Files

  • lib/rss/maker/0.9.rb

Parent

GeneratorBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/0.9.rb, line 185
def to_feed(rss, channel)
end


class RSS::Maker::RSS09::Channel::Links - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Links

In Files

  • lib/rss/maker/0.9.rb

Parent

LinksBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/0.9.rb, line 144
def to_feed(rss, channel)
  return if @links.empty?
  @links.first.to_feed(rss, channel)
end


class RSS::Maker::RSS09::Channel::Links::Link - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Links::Link

In Files

  • lib/rss/maker/0.9.rb

Parent

LinkBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/0.9.rb, line 150
def to_feed(rss, channel)
  if have_required_values?
    channel.link = href
  else
    raise NotSetError.new("maker.channel.link",
                          not_set_required_variables)
  end
end


class RSS::Maker::RSS09::Channel::SkipDays - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::SkipDays

In Files

  • lib/rss/maker/0.9.rb

Parent

SkipDaysBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/0.9.rb, line 71
def to_feed(rss, channel)
  unless @days.empty?
    skipDays = Rss::Channel::SkipDays.new
    channel.skipDays = skipDays
    set_parent(skipDays, channel)
    @days.each do |day|
      day.to_feed(rss, skipDays.days)
    end
  end
end


class RSS::Maker::RSS09::Channel::SkipDays::Day - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::SkipDays::Day

In Files

  • lib/rss/maker/0.9.rb

Parent

DayBase

Public Instance Methods

to_feed(rss, days) click to toggle source
# File lib/rss/maker/0.9.rb, line 83
def to_feed(rss, days)
  day = Rss::Channel::SkipDays::Day.new
  set = setup_values(day)
  if set
    days << day
    set_parent(day, days)
    setup_other_elements(rss, day)
  end
end


class RSS::Maker::RSS09::Channel::SkipHours - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::SkipHours

In Files

  • lib/rss/maker/0.9.rb

Parent

SkipHoursBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/0.9.rb, line 101
def to_feed(rss, channel)
  unless @hours.empty?
    skipHours = Rss::Channel::SkipHours.new
    channel.skipHours = skipHours
    set_parent(skipHours, channel)
    @hours.each do |hour|
      hour.to_feed(rss, skipHours.hours)
    end
  end
end


class RSS::Maker::RSS09::Channel::SkipHours::Hour - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::SkipHours::Hour

In Files

  • lib/rss/maker/0.9.rb

Parent

HourBase

Public Instance Methods

to_feed(rss, hours) click to toggle source
# File lib/rss/maker/0.9.rb, line 113
def to_feed(rss, hours)
  hour = Rss::Channel::SkipHours::Hour.new
  set = setup_values(hour)
  if set
    hours << hour
    set_parent(hour, hours)
    setup_other_elements(rss, hour)
  end
end


class RSS::Maker::RSS09::Channel::Title - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Channel::Title

In Files

  • lib/rss/maker/0.9.rb

Parent

TitleBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/0.9.rb, line 212
def to_feed(rss, channel)
  channel.title = content if have_required_values?
end


class RSS::Maker::RSS09::Image - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Image

In Files

  • lib/rss/maker/0.9.rb

Parent

ImageBase

Public Instance Methods

to_feed(rss) click to toggle source
# File lib/rss/maker/0.9.rb, line 224
def to_feed(rss)
  image = Rss::Channel::Image.new
  set = setup_values(image)
  if set
    image.link = link
    rss.channel.image = image
    set_parent(image, rss.channel)
    setup_other_elements(rss, image)
  elsif required_element?
    raise NotSetError.new("maker.image", not_set_required_variables)
  end
end


class RSS::Maker::RSS09::Items - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items

In Files

  • lib/rss/maker/0.9.rb

Parent

ItemsBase

Public Instance Methods

to_feed(rss) click to toggle source
# File lib/rss/maker/0.9.rb, line 248
def to_feed(rss)
  if rss.channel
    normalize.each do |item|
      item.to_feed(rss)
    end
    setup_other_elements(rss, rss.items)
  end
end


class RSS::Maker::RSS09::Items::Item - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item

In Files

  • lib/rss/maker/0.9.rb

Parent

ItemBase

Public Instance Methods

to_feed(rss) click to toggle source
# File lib/rss/maker/0.9.rb, line 258
def to_feed(rss)
  item = Rss::Channel::Item.new
  setup_values(item)
  _not_set_required_variables = not_set_required_variables
  if _not_set_required_variables.empty?
    rss.items << item
    set_parent(item, rss.channel)
    setup_other_elements(rss, item)
  elsif variable_is_set?
    raise NotSetError.new("maker.items", _not_set_required_variables)
  end
end


class RSS::Maker::RSS09::Items::Item::Authors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Authors

In Files

  • lib/rss/maker/0.9.rb

Parent

AuthorsBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 371
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Authors::Author - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Authors::Author

In Files

  • lib/rss/maker/0.9.rb

Parent

AuthorBase


class RSS::Maker::RSS09::Items::Item::Categories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Categories

In Files

  • lib/rss/maker/0.9.rb

Parent

CategoriesBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 363
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Categories::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Categories::Category

In Files

  • lib/rss/maker/0.9.rb

Parent

CategoryBase


class RSS::Maker::RSS09::Items::Item::Content - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Content

In Files

  • lib/rss/maker/0.9.rb

Parent

ContentBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/0.9.rb, line 426
def to_feed(rss, item)
end


class RSS::Maker::RSS09::Items::Item::Contributors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Contributors

In Files

  • lib/rss/maker/0.9.rb

Parent

ContributorsBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/0.9.rb, line 402
def to_feed(rss, item)
end


class RSS::Maker::RSS09::Items::Item::Contributors::Contributor - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Contributors::Contributor

In Files

  • lib/rss/maker/0.9.rb

Parent

ContributorBase


class RSS::Maker::RSS09::Items::Item::Description - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Description

In Files

  • lib/rss/maker/0.9.rb

Parent

DescriptionBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/0.9.rb, line 415
def to_feed(rss, item)
  item.description = content if have_required_values?
end


class RSS::Maker::RSS09::Items::Item::Enclosure - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Enclosure

In Files

  • lib/rss/maker/0.9.rb

Parent

EnclosureBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 291
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Guid - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Guid

In Files

  • lib/rss/maker/0.9.rb

Parent

GuidBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 286
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Links - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Links

In Files

  • lib/rss/maker/0.9.rb

Parent

LinksBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/0.9.rb, line 379
def to_feed(rss, item)
  return if @links.empty?
  @links.first.to_feed(rss, item)
end


class RSS::Maker::RSS09::Items::Item::Links::Link - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Links::Link

In Files

  • lib/rss/maker/0.9.rb

Parent

LinkBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/0.9.rb, line 385
def to_feed(rss, item)
  if have_required_values?
    item.link = href
  else
    raise NotSetError.new("maker.link",
                          not_set_required_variables)
  end
end


class RSS::Maker::RSS09::Items::Item::Rights - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Rights

In Files

  • lib/rss/maker/0.9.rb

Parent

RightsBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/0.9.rb, line 410
def to_feed(rss, item)
end


class RSS::Maker::RSS09::Items::Item::Source - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source

In Files

  • lib/rss/maker/0.9.rb

Parent

SourceBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 296
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Source::Authors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Authors

In Files

  • lib/rss/maker/0.9.rb

Parent

AuthorsBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 300
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Source::Authors::Author - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Authors::Author

In Files

  • lib/rss/maker/0.9.rb

Parent

AuthorBase


class RSS::Maker::RSS09::Items::Item::Source::Categories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Categories

In Files

  • lib/rss/maker/0.9.rb

Parent

CategoriesBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 308
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Source::Categories::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Categories::Category

In Files

  • lib/rss/maker/0.9.rb

Parent

CategoryBase


class RSS::Maker::RSS09::Items::Item::Source::Contributors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Contributors

In Files

  • lib/rss/maker/0.9.rb

Parent

ContributorsBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 316
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Source::Contributors::Contributor - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Contributors::Contributor

In Files

  • lib/rss/maker/0.9.rb

Parent

ContributorBase


class RSS::Maker::RSS09::Items::Item::Source::Generator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Generator

In Files

  • lib/rss/maker/0.9.rb

Parent

GeneratorBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 324
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Source::Icon - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Icon

In Files

  • lib/rss/maker/0.9.rb

Parent

IconBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 329
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Source::Links - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Links

In Files

  • lib/rss/maker/0.9.rb

Parent

LinksBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 334
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Source::Links::Link - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Links::Link

In Files

  • lib/rss/maker/0.9.rb

Parent

LinkBase


class RSS::Maker::RSS09::Items::Item::Source::Logo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Logo

In Files

  • lib/rss/maker/0.9.rb

Parent

LogoBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 342
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Source::Rights - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Rights

In Files

  • lib/rss/maker/0.9.rb

Parent

RightsBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 347
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Source::Subtitle - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Subtitle

In Files

  • lib/rss/maker/0.9.rb

Parent

SubtitleBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 352
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Source::Title - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Source::Title

In Files

  • lib/rss/maker/0.9.rb

Parent

TitleBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/0.9.rb, line 357
def to_feed(*args)
end


class RSS::Maker::RSS09::Items::Item::Title - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Items::Item::Title

In Files

  • lib/rss/maker/0.9.rb

Parent

TitleBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/0.9.rb, line 431
def to_feed(rss, item)
  item.title = content if have_required_values?
end


class RSS::Maker::RSS09::Textinput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS09::Textinput

In Files

  • lib/rss/maker/0.9.rb

Parent

TextinputBase

Public Instance Methods

to_feed(rss) click to toggle source
# File lib/rss/maker/0.9.rb, line 444
def to_feed(rss)
  textInput = Rss::Channel::TextInput.new
  set = setup_values(textInput)
  if set
    rss.channel.textInput = textInput
    set_parent(textInput, rss.channel)
    setup_other_elements(rss, textInput)
  end
end


class RSS::Maker::RSS10 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10

In Files

  • lib/rss/maker/1.0.rb

Parent

RSSBase

Public Class Methods

new(feed_version="1.0") click to toggle source
# File lib/rss/maker/1.0.rb, line 10
def initialize(feed_version="1.0")
  super
  @feed_type = "rss"
end


class RSS::Maker::RSS10::Channel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel

In Files

  • lib/rss/maker/1.0.rb

Parent

ChannelBase

Included Modules

  • RSS::Maker::SetupDefaultLanguage

Public Instance Methods

to_feed(rss) click to toggle source
# File lib/rss/maker/1.0.rb, line 30
def to_feed(rss)
  set_default_values do
    _not_set_required_variables = not_set_required_variables
    if _not_set_required_variables.empty?
      channel = RDF::Channel.new(@about)
      setup_values(channel)
      channel.dc_dates.clear
      rss.channel = channel
      set_parent(channel, rss)
      setup_items(rss)
      setup_image(rss)
      setup_textinput(rss)
      setup_other_elements(rss, channel)
    else
      raise NotSetError.new("maker.channel", _not_set_required_variables)
    end
  end
end


class RSS::Maker::RSS10::Channel::Authors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Authors

In Files

  • lib/rss/maker/1.0.rb

Parent

AuthorsBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/1.0.rb, line 145
def to_feed(rss, channel)
end


class RSS::Maker::RSS10::Channel::Authors::Author - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Authors::Author

In Files

  • lib/rss/maker/1.0.rb

Parent

AuthorBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/1.0.rb, line 149
def to_feed(rss, channel)
end


class RSS::Maker::RSS10::Channel::Categories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Categories

In Files

  • lib/rss/maker/1.0.rb

Parent

CategoriesBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 114
def to_feed(*args)
end


class RSS::Maker::RSS10::Channel::Categories::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Categories::Category

In Files

  • lib/rss/maker/1.0.rb

Parent

CategoryBase


class RSS::Maker::RSS10::Channel::Cloud - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Cloud

In Files

  • lib/rss/maker/1.0.rb

Parent

CloudBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 109
def to_feed(*args)
end


class RSS::Maker::RSS10::Channel::Contributors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Contributors

In Files

  • lib/rss/maker/1.0.rb

Parent

ContributorsBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/1.0.rb, line 155
def to_feed(rss, channel)
end


class RSS::Maker::RSS10::Channel::Contributors::Contributor - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Contributors::Contributor

In Files

  • lib/rss/maker/1.0.rb

Parent

ContributorBase


class RSS::Maker::RSS10::Channel::Copyright - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Copyright

In Files

  • lib/rss/maker/1.0.rb

Parent

CopyrightBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/1.0.rb, line 168
def to_feed(rss, channel)
end


class RSS::Maker::RSS10::Channel::Description - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Description

In Files

  • lib/rss/maker/1.0.rb

Parent

DescriptionBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/1.0.rb, line 173
def to_feed(rss, channel)
  channel.description = content if have_required_values?
end


class RSS::Maker::RSS10::Channel::Generator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Generator

In Files

  • lib/rss/maker/1.0.rb

Parent

GeneratorBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/1.0.rb, line 163
def to_feed(rss, channel)
end


class RSS::Maker::RSS10::Channel::Links - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Links

In Files

  • lib/rss/maker/1.0.rb

Parent

LinksBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/1.0.rb, line 122
def to_feed(rss, channel)
  return if @links.empty?
  @links.first.to_feed(rss, channel)
end


class RSS::Maker::RSS10::Channel::Links::Link - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Links::Link

In Files

  • lib/rss/maker/1.0.rb

Parent

LinkBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/1.0.rb, line 128
def to_feed(rss, channel)
  if have_required_values?
    channel.link = href
  else
    raise NotSetError.new("maker.channel.link",
                          not_set_required_variables)
  end
end


class RSS::Maker::RSS10::Channel::SkipDays - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::SkipDays

In Files

  • lib/rss/maker/1.0.rb

Parent

SkipDaysBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 93
def to_feed(*args)
end


class RSS::Maker::RSS10::Channel::SkipDays::Day - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::SkipDays::Day

In Files

  • lib/rss/maker/1.0.rb

Parent

DayBase


class RSS::Maker::RSS10::Channel::SkipHours - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::SkipHours

In Files

  • lib/rss/maker/1.0.rb

Parent

SkipHoursBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 101
def to_feed(*args)
end


class RSS::Maker::RSS10::Channel::SkipHours::Hour - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::SkipHours::Hour

In Files

  • lib/rss/maker/1.0.rb

Parent

HourBase


class RSS::Maker::RSS10::Channel::Title - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Channel::Title

In Files

  • lib/rss/maker/1.0.rb

Parent

TitleBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/1.0.rb, line 184
def to_feed(rss, channel)
  channel.title = content if have_required_values?
end


class RSS::Maker::RSS10::Image - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Image

In Files

  • lib/rss/maker/1.0.rb

Parent

ImageBase

Public Instance Methods

have_required_values?() click to toggle source
# File lib/rss/maker/1.0.rb, line 208
def have_required_values?
  super and @maker.channel.have_required_values?
end
to_feed(rss) click to toggle source
# File lib/rss/maker/1.0.rb, line 196
def to_feed(rss)
  if @url
    image = RDF::Image.new(@url)
    set = setup_values(image)
    if set
      rss.image = image
      set_parent(image, rss)
      setup_other_elements(rss, image)
    end
  end
end


class RSS::Maker::RSS10::Items - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items

In Files

  • lib/rss/maker/1.0.rb

Parent

ItemsBase

Public Instance Methods

to_feed(rss) click to toggle source
# File lib/rss/maker/1.0.rb, line 223
def to_feed(rss)
  if rss.channel
    normalize.each do |item|
      item.to_feed(rss)
    end
    setup_other_elements(rss, rss.items)
  end
end


class RSS::Maker::RSS10::Items::Item - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item

In Files

  • lib/rss/maker/1.0.rb

Parent

ItemBase

Public Instance Methods

to_feed(rss) click to toggle source
# File lib/rss/maker/1.0.rb, line 233
def to_feed(rss)
  set_default_values do
    item = RDF::Item.new(link)
    set = setup_values(item)
    if set
      item.dc_dates.clear
      rss.items << item
      set_parent(item, rss)
      setup_other_elements(rss, item)
    elsif !have_required_values?
      raise NotSetError.new("maker.item", not_set_required_variables)
    end
  end
end


class RSS::Maker::RSS10::Items::Item::Authors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Authors

In Files

  • lib/rss/maker/1.0.rb

Parent

AuthorsBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 351
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Authors::Author - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Authors::Author

In Files

  • lib/rss/maker/1.0.rb

Parent

AuthorBase


class RSS::Maker::RSS10::Items::Item::Categories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Categories

In Files

  • lib/rss/maker/1.0.rb

Parent

CategoriesBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 343
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Categories::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Categories::Category

In Files

  • lib/rss/maker/1.0.rb

Parent

CategoryBase


class RSS::Maker::RSS10::Items::Item::Content - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Content

In Files

  • lib/rss/maker/1.0.rb

Parent

ContentBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/1.0.rb, line 391
def to_feed(rss, item)
end


class RSS::Maker::RSS10::Items::Item::Contributors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Contributors

In Files

  • lib/rss/maker/1.0.rb

Parent

ContributorsBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/1.0.rb, line 367
def to_feed(rss, item)
end


class RSS::Maker::RSS10::Items::Item::Contributors::Contributor - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Contributors::Contributor

In Files

  • lib/rss/maker/1.0.rb

Parent

ContributorBase


class RSS::Maker::RSS10::Items::Item::Description - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Description

In Files

  • lib/rss/maker/1.0.rb

Parent

DescriptionBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/1.0.rb, line 380
def to_feed(rss, item)
  item.description = content if have_required_values?
end


class RSS::Maker::RSS10::Items::Item::Enclosure - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Enclosure

In Files

  • lib/rss/maker/1.0.rb

Parent

EnclosureBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 271
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Guid - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Guid

In Files

  • lib/rss/maker/1.0.rb

Parent

GuidBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 266
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Links - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Links

In Files

  • lib/rss/maker/1.0.rb

Parent

LinksBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 359
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Links::Link - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Links::Link

In Files

  • lib/rss/maker/1.0.rb

Parent

LinkBase


class RSS::Maker::RSS10::Items::Item::Rights - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Rights

In Files

  • lib/rss/maker/1.0.rb

Parent

RightsBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/1.0.rb, line 375
def to_feed(rss, item)
end


class RSS::Maker::RSS10::Items::Item::Source - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source

In Files

  • lib/rss/maker/1.0.rb

Parent

SourceBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 276
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Source::Authors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Authors

In Files

  • lib/rss/maker/1.0.rb

Parent

AuthorsBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 280
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Source::Authors::Author - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Authors::Author

In Files

  • lib/rss/maker/1.0.rb

Parent

AuthorBase


class RSS::Maker::RSS10::Items::Item::Source::Categories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Categories

In Files

  • lib/rss/maker/1.0.rb

Parent

CategoriesBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 288
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Source::Categories::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Categories::Category

In Files

  • lib/rss/maker/1.0.rb

Parent

CategoryBase


class RSS::Maker::RSS10::Items::Item::Source::Contributors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Contributors

In Files

  • lib/rss/maker/1.0.rb

Parent

ContributorsBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 296
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Source::Contributors::Contributor - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Contributors::Contributor

In Files

  • lib/rss/maker/1.0.rb

Parent

ContributorBase


class RSS::Maker::RSS10::Items::Item::Source::Generator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Generator

In Files

  • lib/rss/maker/1.0.rb

Parent

GeneratorBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 304
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Source::Icon - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Icon

In Files

  • lib/rss/maker/1.0.rb

Parent

IconBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 309
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Source::Links - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Links

In Files

  • lib/rss/maker/1.0.rb

Parent

LinksBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 314
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Source::Links::Link - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Links::Link

In Files

  • lib/rss/maker/1.0.rb

Parent

LinkBase


class RSS::Maker::RSS10::Items::Item::Source::Logo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Logo

In Files

  • lib/rss/maker/1.0.rb

Parent

LogoBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 322
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Source::Rights - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Rights

In Files

  • lib/rss/maker/1.0.rb

Parent

RightsBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 327
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Source::Subtitle - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Subtitle

In Files

  • lib/rss/maker/1.0.rb

Parent

SubtitleBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 332
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Source::Title - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Source::Title

In Files

  • lib/rss/maker/1.0.rb

Parent

TitleBase

Public Instance Methods

to_feed(*args) click to toggle source
# File lib/rss/maker/1.0.rb, line 337
def to_feed(*args)
end


class RSS::Maker::RSS10::Items::Item::Title - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Items::Item::Title

In Files

  • lib/rss/maker/1.0.rb

Parent

TitleBase

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/1.0.rb, line 396
def to_feed(rss, item)
  item.title = content if have_required_values?
end


class RSS::Maker::RSS10::Textinput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS10::Textinput

In Files

  • lib/rss/maker/1.0.rb

Parent

TextinputBase

Public Instance Methods

have_required_values?() click to toggle source
# File lib/rss/maker/1.0.rb, line 421
def have_required_values?
  super and @maker.channel.have_required_values?
end
to_feed(rss) click to toggle source
# File lib/rss/maker/1.0.rb, line 409
def to_feed(rss)
  if @link
    textinput = RDF::Textinput.new(@link)
    set = setup_values(textinput)
    if set
      rss.textinput = textinput
      set_parent(textinput, rss)
      setup_other_elements(rss, textinput)
    end
  end
end


class RSS::Maker::RSS20 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09

Public Class Methods

new(feed_version="2.0") click to toggle source
# File lib/rss/maker/2.0.rb, line 10
def initialize(feed_version="2.0")
  super
end


class RSS::Maker::RSS20::Channel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Channel

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Channel


class RSS::Maker::RSS20::Channel::Categories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Channel::Categories

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Channel::Categories

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/2.0.rb, line 49
def to_feed(rss, channel)
  @categories.each do |category|
    category.to_feed(rss, channel)
  end
end


class RSS::Maker::RSS20::Channel::Categories::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Channel::Categories::Category

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Channel::Categories::Category

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/2.0.rb, line 56
def to_feed(rss, channel)
  category = Rss::Channel::Category.new
  set = setup_values(category)
  if set
    channel.categories << category
    set_parent(category, channel)
    setup_other_elements(rss, category)
  end
end


class RSS::Maker::RSS20::Channel::Cloud - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Channel::Cloud

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Channel::Cloud

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/2.0.rb, line 32
def to_feed(rss, channel)
  cloud = Rss::Channel::Cloud.new
  set = setup_values(cloud)
  if set
    channel.cloud = cloud
    set_parent(cloud, channel)
    setup_other_elements(rss, cloud)
  end
end


class RSS::Maker::RSS20::Channel::Generator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Channel::Generator

In Files

  • lib/rss/maker/2.0.rb

Parent

GeneratorBase

Public Instance Methods

to_feed(rss, channel) click to toggle source
# File lib/rss/maker/2.0.rb, line 74
def to_feed(rss, channel)
  channel.generator = content
end


class RSS::Maker::RSS20::Channel::SkipDays - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Channel::SkipDays

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Channel::SkipDays


class RSS::Maker::RSS20::Channel::SkipDays::Day - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Channel::SkipDays::Day

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Channel::SkipDays::Day


class RSS::Maker::RSS20::Channel::SkipHours - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Channel::SkipHours

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Channel::SkipHours


class RSS::Maker::RSS20::Channel::SkipHours::Hour - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Channel::SkipHours::Hour

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Channel::SkipHours::Hour


class RSS::Maker::RSS20::Image - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Image

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Image


class RSS::Maker::RSS20::Items - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Items

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Items


class RSS::Maker::RSS20::Items::Item - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Items::Item

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Items::Item


class RSS::Maker::RSS20::Items::Item::Authors - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Items::Item::Authors

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Items::Item::Authors

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/2.0.rb, line 202
def to_feed(rss, item)
  return if @authors.empty?
  @authors.first.to_feed(rss, item)
end


class RSS::Maker::RSS20::Items::Item::Authors::Author - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Items::Item::Authors::Author

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Items::Item::Authors::Author

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/2.0.rb, line 208
def to_feed(rss, item)
  item.author = name
end


class RSS::Maker::RSS20::Items::Item::Categories - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Items::Item::Categories

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Items::Item::Categories

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/2.0.rb, line 177
def to_feed(rss, item)
  @categories.each do |category|
    category.to_feed(rss, item)
  end
end


class RSS::Maker::RSS20::Items::Item::Categories::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Items::Item::Categories::Category

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Items::Item::Categories::Category

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/2.0.rb, line 184
def to_feed(rss, item)
  category = Rss::Channel::Item::Category.new
  set = setup_values(category)
  if set
    item.categories << category
    set_parent(category, item)
    setup_other_elements(rss)
  end
end


class RSS::Maker::RSS20::Items::Item::Enclosure - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Items::Item::Enclosure

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Items::Item::Enclosure

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/2.0.rb, line 130
def to_feed(rss, item)
  enclosure = Rss::Channel::Item::Enclosure.new
  set = setup_values(enclosure)
  if set
    item.enclosure = enclosure
    set_parent(enclosure, item)
    setup_other_elements(rss, enclosure)
  end
end


class RSS::Maker::RSS20::Items::Item::Guid - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Items::Item::Guid

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Items::Item::Guid

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/2.0.rb, line 113
def to_feed(rss, item)
  guid = Rss::Channel::Item::Guid.new
  set = setup_values(guid)
  if set
    item.guid = guid
    set_parent(guid, item)
    setup_other_elements(rss, guid)
  end
end


class RSS::Maker::RSS20::Items::Item::Source - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Items::Item::Source

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Items::Item::Source

Public Instance Methods

to_feed(rss, item) click to toggle source
# File lib/rss/maker/2.0.rb, line 147
def to_feed(rss, item)
  source = Rss::Channel::Item::Source.new
  set = setup_values(source)
  if set
    item.source = source
    set_parent(source, item)
    setup_other_elements(rss, source)
  end
end


class RSS::Maker::RSS20::Items::Item::Source::Links - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Items::Item::Source::Links

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Items::Item::Source::Links

Public Instance Methods

to_feed(rss, source) click to toggle source
# File lib/rss/maker/2.0.rb, line 163
def to_feed(rss, source)
  return if @links.empty?
  @links.first.to_feed(rss, source)
end


class RSS::Maker::RSS20::Items::Item::Source::Links::Link - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Items::Item::Source::Links::Link

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Items::Item::Source::Links::Link

Public Instance Methods

to_feed(rss, source) click to toggle source
# File lib/rss/maker/2.0.rb, line 169
def to_feed(rss, source)
  source.url = href
end


class RSS::Maker::RSS20::Textinput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSS20::Textinput

In Files

  • lib/rss/maker/2.0.rb

Parent

RSS::Maker::RSS09::Textinput


class RSS::Maker::RSSBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::RSSBase

In Files

  • lib/rss/maker/base.rb
  • lib/rss/maker/taxonomy.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::TaxonomyTopicModel

Attributes

encoding[RW]
feed_version[R]
rss_version[R]
standalone[RW]
version[RW]

Public Class Methods

make(*args, &block) click to toggle source
# File lib/rss/maker/base.rb, line 401
def make(*args, &block)
  new(*args).make(&block)
end
new(feed_version) click to toggle source
# File lib/rss/maker/base.rb, line 427
def initialize(feed_version)
  super(self)
  @feed_type = nil
  @feed_subtype = nil
  @feed_version = feed_version
  @version = "1.0"
  @encoding = "UTF-8"
  @standalone = nil
end

Public Instance Methods

make() { |self| ... } click to toggle source
# File lib/rss/maker/base.rb, line 437
def make
  yield(self)
  to_feed
end
to_feed() click to toggle source
# File lib/rss/maker/base.rb, line 442
def to_feed
  feed = make_feed
  setup_xml_stylesheets(feed)
  setup_elements(feed)
  setup_other_elements(feed)
  feed.validate
  feed
end


module RSS::Maker::SetupDefaultDate - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::SetupDefaultDate

In Files

  • lib/rss/maker/base.rb


module RSS::Maker::SetupDefaultLanguage - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::SetupDefaultLanguage

In Files

  • lib/rss/maker/base.rb


module RSS::Maker::SlashModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::SlashModel

In Files

  • lib/rss/maker/slash.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/slash.rb, line 7
def self.append_features(klass)
  super

  ::RSS::SlashModel::ELEMENT_INFOS.each do |name, type|
    full_name = "#{RSS::SLASH_PREFIX}_#{name}"
    case type
    when :csv_integer
      klass.def_csv_element(full_name, :integer)
    else
      klass.def_other_element(full_name)
    end
  end

  klass.module_eval do
    alias_method(:slash_hit_parades, :slash_hit_parade)
    alias_method(:slash_hit_parades=, :slash_hit_parade=)
  end
end


module RSS::Maker::SyndicationModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::SyndicationModel

In Files

  • lib/rss/maker/syndication.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/syndication.rb, line 7
def self.append_features(klass)
  super

  ::RSS::SyndicationModel::ELEMENTS.each do |name|
    klass.def_other_element(name)
  end
end


module RSS::Maker::TaxonomyTopicModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::TaxonomyTopicModel

In Files

  • lib/rss/maker/taxonomy.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/taxonomy.rb, line 40
def self.append_features(klass)
  super

  class_name = "TaxonomyTopics"
  klass.def_classed_elements("#{TAXO_PREFIX}_topic", "value", class_name)
end
install_taxo_topic(klass) click to toggle source
# File lib/rss/maker/taxonomy.rb, line 47
      def self.install_taxo_topic(klass)
        klass.module_eval("          class TaxonomyTopics < TaxonomyTopicsBase
            class TaxonomyTopic < TaxonomyTopicBase
              DublinCoreModel.install_dublin_core(self)
              TaxonomyTopicsModel.install_taxo_topics(self)

              def to_feed(feed, current)
                if current.respond_to?(:taxo_topics)
                  topic = current.class::TaxonomyTopic.new(value)
                  topic.taxo_link = value
                  taxo_topics.to_feed(feed, topic) if taxo_topics
                  current.taxo_topics << topic
                  setup_other_elements(feed, topic)
                end
              end
            end
          end
", __FILE__, __LINE__ + 1)
      end


class RSS::Maker::TaxonomyTopicModel::TaxonomyTopicsBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::TaxonomyTopicModel::TaxonomyTopicsBase

In Files

  • lib/rss/maker/taxonomy.rb

Parent

RSS::Maker::Base


class RSS::Maker::TaxonomyTopicModel::TaxonomyTopicsBase::TaxonomyTopicBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::TaxonomyTopicModel::TaxonomyTopicsBase::TaxonomyTopicBase

In Files

  • lib/rss/maker/taxonomy.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::DublinCoreModel
  • RSS::Maker::TaxonomyTopicsModel

Attributes

taxo_link[RW]
taxo_link=[RW]
value[RW]

Public Instance Methods

have_required_values?() click to toggle source
# File lib/rss/maker/taxonomy.rb, line 81
def have_required_values?
  @value
end


module RSS::Maker::TaxonomyTopicsModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::TaxonomyTopicsModel

In Files

  • lib/rss/maker/taxonomy.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/taxonomy.rb, line 8
def self.append_features(klass)
  super

  klass.def_classed_element("#{RSS::TAXO_PREFIX}_topics",
                            "TaxonomyTopics")
end
install_taxo_topics(klass) click to toggle source
# File lib/rss/maker/taxonomy.rb, line 15
      def self.install_taxo_topics(klass)
        klass.module_eval("          class TaxonomyTopics < TaxonomyTopicsBase
            def to_feed(feed, current)
              if current.respond_to?(:taxo_topics)
                topics = current.class::TaxonomyTopics.new
                bag = topics.Bag
                @resources.each do |resource|
                  bag.lis << RDF::Bag::Li.new(resource)
                end
                current.taxo_topics = topics
              end
            end
          end
", __FILE__, __LINE__ + 1)
      end


class RSS::Maker::TaxonomyTopicsModel::TaxonomyTopicsBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::TaxonomyTopicsModel::TaxonomyTopicsBase

In Files

  • lib/rss/maker/taxonomy.rb

Parent

RSS::Maker::Base

Attributes

resources[R]


class RSS::Maker::TextinputBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::TextinputBase

In Files

  • lib/rss/maker/base.rb
  • lib/rss/maker/dublincore.rb

Parent

RSS::Maker::Base

Included Modules

  • RSS::Maker::DublinCoreModel


module RSS::Maker::TrackBackModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Maker::TrackBackModel

In Files

  • lib/rss/maker/trackback.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/maker/trackback.rb, line 8
def self.append_features(klass)
  super

  klass.def_other_element("#{RSS::TRACKBACK_PREFIX}_ping")
  klass.def_classed_elements("#{RSS::TRACKBACK_PREFIX}_about", "value",
                             "TrackBackAbouts")
end


class RSS::Maker::TrackBackModel::TrackBackAboutsBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::TrackBackModel::TrackBackAboutsBase

In Files

  • lib/rss/maker/trackback.rb

Parent

RSS::Maker::Base


class RSS::Maker::TrackBackModel::TrackBackAboutsBase::TrackBackAboutBase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::TrackBackModel::TrackBackAboutsBase::TrackBackAboutBase

In Files

  • lib/rss/maker/trackback.rb

Parent

RSS::Maker::Base

Attributes

content[RW]
content=[RW]
resource[RW]
resource=[RW]
value[RW]

Public Instance Methods

have_required_values?() click to toggle source
# File lib/rss/maker/trackback.rb, line 28
def have_required_values?
  @value
end
to_feed(feed, current) click to toggle source
# File lib/rss/maker/trackback.rb, line 32
def to_feed(feed, current)
  if current.respond_to?(:trackback_abouts) and have_required_values?
    about = current.class::TrackBackAbout.new
    setup_values(about)
    setup_other_elements(about)
    current.trackback_abouts << about
  end
end


class RSS::Maker::XMLStyleSheets - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::XMLStyleSheets

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base


class RSS::Maker::XMLStyleSheets::XMLStyleSheet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Maker::XMLStyleSheets::XMLStyleSheet

In Files

  • lib/rss/maker/base.rb

Parent

RSS::Maker::Base

Public Instance Methods

to_feed(feed) click to toggle source
# File lib/rss/maker/base.rb, line 468
def to_feed(feed)
  xss = ::RSS::XMLStyleSheet.new
  guess_type_if_need(xss)
  set = setup_values(xss)
  if set
    feed.xml_stylesheets << xss
  end
end


class RSS::MissingAttributeError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::MissingAttributeError

Raised if a required attribute is missing.

In Files

  • lib/rss/rss.rb

Parent

RSS::InvalidRSSError

Attributes

attribute[R]
tag[R]

Public Class Methods

new(tag, attribute) click to toggle source
# File lib/rss/rss.rb, line 100
def initialize(tag, attribute)
  @tag, @attribute = tag, attribute
  super("attribute <#{attribute}> is missing in tag <#{tag}>")
end


class RSS::MissingTagError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::MissingTagError

Raised if no matching tag is found.

In Files

  • lib/rss/rss.rb

Parent

RSS::InvalidRSSError

Attributes

parent[R]
tag[R]

Public Class Methods

new(tag, parent) click to toggle source
# File lib/rss/rss.rb, line 78
def initialize(tag, parent)
  @tag, @parent = tag, parent
  super("tag <#{tag}> is missing in tag <#{parent}>")
end


class RSS::NSError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::NSError

In Files

  • lib/rss/parser.rb

Parent

InvalidRSSError

Attributes

prefix[R]
tag[R]
uri[R]

Public Class Methods

new(tag, prefix, require_uri) click to toggle source
# File lib/rss/parser.rb, line 45
def initialize(tag, prefix, require_uri)
  @tag, @prefix, @uri = tag, prefix, require_uri
  super("prefix <#{prefix}> doesn't associate uri " <<
        "<#{require_uri}> in tag <#{tag}>")
end


class RSS::NotAvailableValueError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::NotAvailableValueError

Raised when an incorrect value is used.

In Files

  • lib/rss/rss.rb

Parent

RSS::InvalidRSSError

Attributes

attribute[R]
tag[R]
value[R]

Public Class Methods

new(tag, value, attribute=nil) click to toggle source
# File lib/rss/rss.rb, line 135
def initialize(tag, value, attribute=nil)
  @tag, @value, @attribute = tag, value, attribute
  message = "value <#{value}> of "
  message << "attribute <#{attribute}> of " if attribute
  message << "tag <#{tag}> is not available."
  super(message)
end


class RSS::NotExpectedTagError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::NotExpectedTagError

Raised when an unexpected tag is encountered.

In Files

  • lib/rss/rss.rb

Parent

RSS::InvalidRSSError

Attributes

parent[R]
tag[R]
uri[R]

Public Class Methods

new(tag, uri, parent) click to toggle source
# File lib/rss/rss.rb, line 122
def initialize(tag, uri, parent)
  @tag, @uri, @parent = tag, uri, parent
  super("tag <{#{uri}}#{tag}> is not expected in tag <#{parent}>")
end


class RSS::NotSetError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::NotSetError

Raised when a required variable is not set.

In Files

  • lib/rss/rss.rb

Parent

RSS::Error

Attributes

name[R]
variables[R]

Public Class Methods

new(name, variables) click to toggle source
# File lib/rss/rss.rb, line 176
def initialize(name, variables)
  @name = name
  @variables = variables
  super("required variables of #{@name} are not set: #{@variables.join(', ')}")
end


class RSS::NotValidXMLParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::NotValidXMLParser

In Files

  • lib/rss/parser.rb

Parent

Error

Public Class Methods

new(parser) click to toggle source
# File lib/rss/parser.rb, line 35
def initialize(parser)
  super("#{parser} is not an available XML parser. " <<
        "Available XML parser" <<
        (AVAILABLE_PARSERS.size > 1 ? "s are " : " is ") <<
        "#{AVAILABLE_PARSERS.inspect}.")
end


class RSS::NotWellFormedError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::NotWellFormedError

In Files

  • lib/rss/parser.rb

Parent

Error

Attributes

element[R]
line[R]

Public Class Methods

new(line=nil, element=nil) click to toggle source

Create a new NotWellFormedError for an error at line in element. If a block is given the return value of the block ends up in the error message.

# File lib/rss/parser.rb, line 15
def initialize(line=nil, element=nil)
  message = "This is not well formed XML"
  if element or line
    message << "\nerror occurred"
    message << " in #{element}" if element
    message << " at about #{line} line" if line
  end
  message << "\n#{yield}" if block_given?
  super(message)
end


class RSS::OverlappedPrefixError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::OverlappedPrefixError

In Files

  • lib/rss/rss.rb

Parent

RSS::Error

Attributes

prefix[R]

Public Class Methods

new(prefix) click to toggle source
# File lib/rss/rss.rb, line 66
def initialize(prefix)
  @prefix = prefix
end


class RSS::Parser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Parser

In Files

  • lib/rss/parser.rb

Parent

Object

Public Class Methods

default_parser() click to toggle source
# File lib/rss/parser.rb, line 60
def default_parser
  @@default_parser || AVAILABLE_PARSERS.first
end
default_parser=(new_value) click to toggle source

Set @@::default_parser to new_value if it is one of the available parsers. Else raise NotValidXMLParser error.

# File lib/rss/parser.rb, line 66
def default_parser=(new_value)
  if AVAILABLE_PARSERS.include?(new_value)
    @@default_parser = new_value
  else
    raise NotValidXMLParser.new(new_value)
  end
end
new(rss, parser_class=self.class.default_parser) click to toggle source
# File lib/rss/parser.rb, line 88
def initialize(rss, parser_class=self.class.default_parser)
  @parser = parser_class.new(normalize_rss(rss))
end
parse(rss, do_validate=true, ignore_unknown_element=true, parser_class=default_parser) click to toggle source
# File lib/rss/parser.rb, line 74
def parse(rss, do_validate=true, ignore_unknown_element=true,
          parser_class=default_parser)
  parser = new(rss, parser_class)
  parser.do_validate = do_validate
  parser.ignore_unknown_element = ignore_unknown_element
  parser.parse
end


class RSS::RDF - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::RDF

In Files

  • lib/rss/1.0.rb
  • lib/rss/content/1.0.rb
  • lib/rss/dublincore/1.0.rb
  • lib/rss/image.rb
  • lib/rss/slash.rb
  • lib/rss/syndication.rb
  • lib/rss/taxonomy.rb
  • lib/rss/trackback.rb

Parent

Element

Included Modules

  • RSS::RSS10
  • RSS::RootElementMixin
  • RSS::TaxonomyTopicModel

Constants

PREFIX
URI

Public Class Methods

new(version=nil, encoding=nil, standalone=nil) click to toggle source
# File lib/rss/1.0.rb, line 49
def initialize(version=nil, encoding=nil, standalone=nil)
  super('1.0', version, encoding, standalone)
  @feed_type = "rss"
end
required_uri() click to toggle source
# File lib/rss/1.0.rb, line 24
def required_uri
  URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/1.0.rb, line 54
def full_name
  tag_name_with_prefix(PREFIX)
end


class RSS::TaxonomyTopicsModel::TaxonomyTopics::Bag - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::TaxonomyTopicsModel::TaxonomyTopics::Bag

In Files

  • lib/rss/1.0.rb

Parent

Element

Included Modules

  • RSS::RSS10

Constants

Li

Public Class Methods

new(*args) click to toggle source
# File lib/rss/1.0.rb, line 142
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    @li = args[0] if args[0]
  end
end
required_uri() click to toggle source
# File lib/rss/1.0.rb, line 132
def required_uri
  URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/1.0.rb, line 151
def full_name
  tag_name_with_prefix(PREFIX)
end
setup_maker(target) click to toggle source
# File lib/rss/1.0.rb, line 155
def setup_maker(target)
  lis.each do |li|
    target << li.resource
  end
end


class RSS::RDF::Seq::Li - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::RDF::Seq::Li

In Files

  • lib/rss/1.0.rb

Parent

Element

Included Modules

  • RSS::RSS10

Public Class Methods

new(*args) click to toggle source
# File lib/rss/1.0.rb, line 74
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.resource = args[0]
  end
end
required_uri() click to toggle source
# File lib/rss/1.0.rb, line 63
def required_uri
  URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/1.0.rb, line 83
def full_name
  tag_name_with_prefix(PREFIX)
end


class RSS::RDF::Channel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::RDF::Channel

In Files

  • lib/rss/1.0.rb
  • lib/rss/dublincore/1.0.rb
  • lib/rss/image.rb
  • lib/rss/syndication.rb
  • lib/rss/taxonomy.rb

Parent

Element

Included Modules

  • RSS::RSS10
  • RSS::DublinCoreModel
  • RSS::ImageFaviconModel
  • RSS::SyndicationModel
  • RSS::TaxonomyTopicsModel

Public Class Methods

new(*args) click to toggle source
# File lib/rss/1.0.rb, line 192
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.about = args[0]
  end
end
required_uri() click to toggle source
# File lib/rss/1.0.rb, line 168
def required_uri
  ::RSS::URI
end


class RSS::RDF::Channel::Image - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::RDF::Channel::Image

In Files

  • lib/rss/1.0.rb

Parent

Element

Included Modules

  • RSS::RSS10

Public Class Methods

new(*args) click to toggle source
# File lib/rss/1.0.rb, line 229
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.resource = args[0]
  end
end
required_uri() click to toggle source
# File lib/rss/1.0.rb, line 216
def required_uri
  ::RSS::URI
end


class RSS::RDF::Channel::Items - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::RDF::Channel::Items

In Files

  • lib/rss/1.0.rb

Parent

Element

Included Modules

  • RSS::RSS10

Constants

Seq

Public Class Methods

new(*args) click to toggle source
# File lib/rss/1.0.rb, line 285
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.Seq = args[0]
  end
  self.Seq ||= Seq.new
end
required_uri() click to toggle source
# File lib/rss/1.0.rb, line 276
def required_uri
  ::RSS::URI
end

Public Instance Methods

resources() click to toggle source
# File lib/rss/1.0.rb, line 295
def resources
  if @Seq
    @Seq.lis.collect do |li|
      li.resource
    end
  else
    []
  end
end


class RSS::RDF::Seq - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::RDF::Seq

In Files

  • lib/rss/1.0.rb

Parent

Element

Included Modules

  • RSS::RSS10

Constants

Li

Public Class Methods

new(*args) click to toggle source
# File lib/rss/1.0.rb, line 105
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    @li = args[0] if args[0]
  end
end
required_uri() click to toggle source
# File lib/rss/1.0.rb, line 95
def required_uri
  URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/1.0.rb, line 114
def full_name
  tag_name_with_prefix(PREFIX)
end
setup_maker(target) click to toggle source
# File lib/rss/1.0.rb, line 118
def setup_maker(target)
  lis.each do |li|
    target << li.resource
  end
end


class RSS::RDF::Channel::Textinput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::RDF::Channel::Textinput

In Files

  • lib/rss/1.0.rb

Parent

Element

Included Modules

  • RSS::RSS10

Public Class Methods

new(*args) click to toggle source
# File lib/rss/1.0.rb, line 258
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.resource = args[0]
  end
end
required_uri() click to toggle source
# File lib/rss/1.0.rb, line 245
def required_uri
  ::RSS::URI
end


class RSS::RDF::Image - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::RDF::Image

In Files

  • lib/rss/1.0.rb
  • lib/rss/dublincore/1.0.rb

Parent

Element

Included Modules

  • RSS::RSS10
  • RSS::DublinCoreModel

Public Class Methods

new(*args) click to toggle source
# File lib/rss/1.0.rb, line 330
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.about = args[0]
  end
end
required_uri() click to toggle source
# File lib/rss/1.0.rb, line 313
def required_uri
  ::RSS::URI
end


class RSS::RDF::Item - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::RDF::Item

In Files

  • lib/rss/1.0.rb
  • lib/rss/content/1.0.rb
  • lib/rss/dublincore/1.0.rb
  • lib/rss/image.rb
  • lib/rss/slash.rb
  • lib/rss/taxonomy.rb
  • lib/rss/trackback.rb

Parent

Element

Included Modules

  • RSS::RSS10
  • RSS::ContentModel
  • RSS::DublinCoreModel
  • RSS::ImageItemModel
  • RSS::SlashModel
  • RSS::TaxonomyTopicsModel
  • RSS::TrackBackModel10

Public Class Methods

new(*args) click to toggle source
# File lib/rss/1.0.rb, line 373
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.about = args[0]
  end
end
required_uri() click to toggle source
# File lib/rss/1.0.rb, line 351
def required_uri
  ::RSS::URI
end


class RSS::RDF::Textinput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::RDF::Textinput

In Files

  • lib/rss/1.0.rb
  • lib/rss/dublincore/1.0.rb

Parent

Element

Included Modules

  • RSS::RSS10
  • RSS::DublinCoreModel

Public Class Methods

new(*args) click to toggle source
# File lib/rss/1.0.rb, line 415
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.about = args[0]
  end
end
required_uri() click to toggle source
# File lib/rss/1.0.rb, line 398
def required_uri
  ::RSS::URI
end


class RSS::REXMLLikeXMLParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::REXMLLikeXMLParser

In Files

  • lib/rss/xmlparser.rb

Parent

XML::Parser

Included Modules

  • ::XML::Encoding_ja

Public Instance Methods

character(data) click to toggle source
# File lib/rss/xmlparser.rb, line 46
def character(data)
  @listener.text(data)
end
endElement(name) click to toggle source
# File lib/rss/xmlparser.rb, line 42
def endElement(name)
  @listener.tag_end(name)
end
listener=(listener) click to toggle source
# File lib/rss/xmlparser.rb, line 34
def listener=(listener)
  @listener = listener
end
processingInstruction(target, content) click to toggle source
# File lib/rss/xmlparser.rb, line 54
def processingInstruction(target, content)
  @listener.instruction(target, content)
end
startElement(name, attrs) click to toggle source
# File lib/rss/xmlparser.rb, line 38
def startElement(name, attrs)
  @listener.tag_start(name, attrs)
end
xmlDecl(version, encoding, standalone) click to toggle source
# File lib/rss/xmlparser.rb, line 50
def xmlDecl(version, encoding, standalone)
  @listener.xmldecl(version, encoding, standalone == 1)
end


class RSS::REXMLListener - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::REXMLListener

In Files

  • lib/rss/rexmlparser.rb

Parent

RSS::BaseListener

Included Modules

  • REXML::StreamListener
  • RSS::ListenerMixin

Public Class Methods

raise_for_undefined_entity?() click to toggle source
# File lib/rss/rexmlparser.rb, line 40
def raise_for_undefined_entity?
  false
end

Public Instance Methods

xmldecl(version, encoding, standalone) click to toggle source
# File lib/rss/rexmlparser.rb, line 45
def xmldecl(version, encoding, standalone)
  super(version, encoding, standalone == "yes")
  # Encoding is converted to UTF-8 when REXML parse XML.
  @encoding = 'UTF-8'
end


class RSS::REXMLParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::REXMLParser

In Files

  • lib/rss/rexmlparser.rb

Parent

RSS::BaseParser

Public Class Methods

listener() click to toggle source
# File lib/rss/rexmlparser.rb, line 14
def listener
  REXMLListener
end


module RSS::RSS09 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::RSS09

In Files

  • lib/rss/0.9.rb

Constants

ELEMENTS
NSPOOL

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/0.9.rb, line 9
def self.append_features(klass)
  super

  klass.install_must_call_validator('', "")
end


module RSS::RSS10 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::RSS10

In Files

  • lib/rss/1.0.rb

Constants

ELEMENTS
NSPOOL

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/1.0.rb, line 9
def self.append_features(klass)
  super

  klass.install_must_call_validator('', ::RSS::URI)
end


module RSS::RootElementMixin - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::RootElementMixin

In Files

  • lib/rss/rss.rb

Included Modules

  • RSS::XMLStyleSheetMixin

Attributes

encoding[RW]
feed_subtype[R]
feed_type[R]
feed_version[R]
output_encoding[R]
standalone[RW]
version[RW]

Public Class Methods

new(feed_version, version=nil, encoding=nil, standalone=nil) click to toggle source
# File lib/rss/rss.rb, line 1246
def initialize(feed_version, version=nil, encoding=nil, standalone=nil)
  super()
  @feed_type = nil
  @feed_subtype = nil
  @feed_version = feed_version
  @version = version || '1.0'
  @encoding = encoding
  @standalone = standalone
  @output_encoding = nil
end

Public Instance Methods

feed_info() click to toggle source
# File lib/rss/rss.rb, line 1257
def feed_info
  [@feed_type, @feed_version, @feed_subtype]
end
output_encoding=(enc) click to toggle source
# File lib/rss/rss.rb, line 1261
def output_encoding=(enc)
  @output_encoding = enc
  self.converter = Converter.new(@output_encoding, @encoding)
end
setup_maker(maker) click to toggle source
# File lib/rss/rss.rb, line 1266
def setup_maker(maker)
  maker.version = version
  maker.encoding = encoding
  maker.standalone = standalone

  xml_stylesheets.each do |xss|
    xss.setup_maker(maker)
  end

  super
end
to_atom(type, &block) click to toggle source
# File lib/rss/rss.rb, line 1289
def to_atom(type, &block)
  to_feed("atom:#{type}", &block)
end
to_feed(type, &block) click to toggle source
# File lib/rss/rss.rb, line 1278
def to_feed(type, &block)
  Maker.make(type) do |maker|
    setup_maker(maker)
    block.call(maker) if block
  end
end
to_rss(type, &block) click to toggle source
# File lib/rss/rss.rb, line 1285
def to_rss(type, &block)
  to_feed("rss#{type}", &block)
end
to_xml(type=nil, &block) click to toggle source
# File lib/rss/rss.rb, line 1293
def to_xml(type=nil, &block)
  if type.nil? or same_feed_type?(type)
    to_s
  else
    to_feed(type, &block).to_s
  end
end


class RSS::Rss - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss

In Files

  • lib/rss/0.9.rb
  • lib/rss/2.0.rb
  • lib/rss/content/2.0.rb
  • lib/rss/dublincore/2.0.rb
  • lib/rss/itunes.rb
  • lib/rss/trackback.rb

Parent

Element

Included Modules

  • RSS::RSS09
  • RSS::RootElementMixin

Attributes

feed_version[W]
rss_version[RW]

Public Class Methods

new(feed_version, version=nil, encoding=nil, standalone=nil) click to toggle source
# File lib/rss/0.9.rb, line 29
def initialize(feed_version, version=nil, encoding=nil, standalone=nil)
  super
  @feed_type = "rss"
end

Public Instance Methods

image() click to toggle source
# File lib/rss/0.9.rb, line 42
def image
  if @channel
    @channel.image
  else
    nil
  end
end
items() click to toggle source
# File lib/rss/0.9.rb, line 34
def items
  if @channel
    @channel.items
  else
    []
  end
end
setup_maker_elements(maker) click to toggle source
# File lib/rss/0.9.rb, line 58
def setup_maker_elements(maker)
  super
  items.each do |item|
    item.setup_maker(maker.items)
  end
  image.setup_maker(maker) if image
  textinput.setup_maker(maker) if textinput
end
textinput() click to toggle source
# File lib/rss/0.9.rb, line 50
def textinput
  if @channel
    @channel.textInput
  else
    nil
  end
end


class RSS::Rss::Channel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel

In Files

  • lib/rss/0.9.rb
  • lib/rss/2.0.rb
  • lib/rss/content/2.0.rb
  • lib/rss/dublincore/2.0.rb
  • lib/rss/itunes.rb
  • lib/rss/trackback.rb

Parent

Element

Included Modules

  • RSS::RSS09
  • RSS::DublinCoreModel
  • RSS::ITunesChannelModel

Constants

Category


class RSS::Rss::Channel::Cloud - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::Cloud

In Files

  • lib/rss/0.9.rb

Parent

Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/0.9.rb, line 229
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.domain = args[0]
    self.port = args[1]
    self.path = args[2]
    self.registerProcedure = args[3]
    self.protocol = args[4]
  end
end


class RSS::Rss::Channel::Image - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::Image

In Files

  • lib/rss/0.9.rb

Parent

Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/0.9.rb, line 195
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.url = args[0]
    self.title = args[1]
    self.link = args[2]
    self.width = args[3]
    self.height = args[4]
    self.description = args[5]
  end
end


class RSS::Rss::Channel::Item - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::Item

In Files

  • lib/rss/0.9.rb
  • lib/rss/2.0.rb
  • lib/rss/content/2.0.rb
  • lib/rss/dublincore/2.0.rb
  • lib/rss/itunes.rb
  • lib/rss/trackback.rb

Parent

Element

Included Modules

  • RSS::RSS09
  • RSS::ContentModel
  • RSS::DublinCoreModel
  • RSS::ITunesItemModel
  • RSS::TrackBackModel20


class RSS::Rss::Channel::Item::Category - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::Item::Category

In Files

  • lib/rss/0.9.rb

Parent

Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/0.9.rb, line 353
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.domain = args[0]
    self.content = args[1]
  end
end


class RSS::Rss::Channel::Item::Enclosure - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::Item::Enclosure

In Files

  • lib/rss/0.9.rb

Parent

Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/0.9.rb, line 318
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.url = args[0]
    self.length = args[1]
    self.type = args[2]
  end
end


class RSS::Rss::Channel::Item::Guid - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::Item::Guid

In Files

  • lib/rss/2.0.rb

Parent

Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/2.0.rb, line 73
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.isPermaLink = args[0]
    self.content = args[1]
  end
end

Public Instance Methods

PermaLink?() click to toggle source
# File lib/rss/2.0.rb, line 85
def PermaLink?
  perma = _PermaLink?
  perma or perma.nil?
end
Also aliased as: _PermaLink?
_PermaLink?() click to toggle source
Alias for: PermaLink?


class RSS::Rss::Channel::Item::Source - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::Item::Source

In Files

  • lib/rss/0.9.rb

Parent

Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/0.9.rb, line 285
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.url = args[0]
    self.content = args[1]
  end
end


class RSS::Rss::Channel::SkipDays - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::SkipDays

In Files

  • lib/rss/0.9.rb

Parent

Element

Included Modules

  • RSS::RSS09


class RSS::Rss::Channel::SkipDays::Day - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::SkipDays::Day

In Files

  • lib/rss/0.9.rb

Parent

Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/0.9.rb, line 141
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.content = args[0]
  end
end


class RSS::Rss::Channel::SkipHours - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::SkipHours

In Files

  • lib/rss/0.9.rb

Parent

Element

Included Modules

  • RSS::RSS09


class RSS::Rss::Channel::SkipHours::Hour - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::SkipHours::Hour

In Files

  • lib/rss/0.9.rb

Parent

Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/0.9.rb, line 168
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.content = args[0]
  end
end


class RSS::Rss::Channel::TextInput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::Rss::Channel::TextInput

In Files

  • lib/rss/0.9.rb

Parent

Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/0.9.rb, line 385
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.title = args[0]
    self.description = args[1]
    self.name = args[2]
    self.link = args[3]
  end
end


module RSS::SetupMaker - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::SetupMaker

In Files

  • lib/rss/rss.rb

Public Instance Methods

setup_maker(maker) click to toggle source
# File lib/rss/rss.rb, line 611
def setup_maker(maker)
  target = maker_target(maker)
  unless target.nil?
    setup_maker_attributes(target)
    setup_maker_element(target)
    setup_maker_elements(target)
  end
end


module RSS::SlashModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::SlashModel

In Files

  • lib/rss/slash.rb

Constants

ELEMENT_INFOS

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/slash.rb, line 21
def append_features(klass)
  super

  return if klass.instance_of?(Module)
  klass.install_must_call_validator(SLASH_PREFIX, SLASH_URI)
  ELEMENT_INFOS.each do |name, type, *additional_infos|
    full_name = "#{SLASH_PREFIX}_#{name}"
    klass.install_text_element(full_name, SLASH_URI, "?",
                               full_name, type, name)
  end

  klass.module_eval do
    alias_method(:slash_hit_parades, :slash_hit_parade)
    undef_method(:slash_hit_parade)
    alias_method(:slash_hit_parade, :slash_hit_parade_content)
  end
end


module RSS::SyndicationModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::SyndicationModel

In Files

  • lib/rss/syndication.rb

Constants

ELEMENTS
SY_UPDATEPERIOD_AVAILABLE_VALUES

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/syndication.rb, line 16
    def self.append_features(klass)
      super

      klass.install_must_call_validator(SY_PREFIX, SY_URI)
      klass.module_eval do
        [
          ["updatePeriod"],
          ["updateFrequency", :positive_integer]
        ].each do |name, type|
          install_text_element(name, SY_URI, "?",
                               "#{SY_PREFIX}_#{name}", type,
                               "#{SY_PREFIX}:#{name}")
        end

        %w(updateBase).each do |name|
          install_date_element(name, SY_URI, "?",
                               "#{SY_PREFIX}_#{name}", 'w3cdtf',
                               "#{SY_PREFIX}:#{name}")
        end
      end

      klass.module_eval("        alias_method(:_sy_updatePeriod=, :sy_updatePeriod=)
        def sy_updatePeriod=(new_value)
          new_value = new_value.strip
          validate_sy_updatePeriod(new_value) if @do_validate
          self._sy_updatePeriod = new_value
        end
", __FILE__, __LINE__ + 1)
    end


module RSS::TaxonomyTopicModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::TaxonomyTopicModel

In Files

  • lib/rss/taxonomy.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/taxonomy.rb, line 91
def self.append_features(klass)
  super
  var_name = "#{TAXO_PREFIX}_topic"
  klass.install_have_children_element("topic", TAXO_URI, "*", var_name)
end


class RSS::TaxonomyTopicModel::TaxonomyTopic - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::TaxonomyTopicModel::TaxonomyTopic

In Files

  • lib/rss/taxonomy.rb

Parent

RSS::Element

Included Modules

  • RSS::RSS10
  • RSS::DublinCoreModel
  • RSS::TaxonomyTopicsModel

Public Class Methods

new(*args) click to toggle source
# File lib/rss/taxonomy.rb, line 119
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.about = args[0]
  end
end
required_prefix() click to toggle source
# File lib/rss/taxonomy.rb, line 104
def required_prefix
  TAXO_PREFIX
end
required_uri() click to toggle source
# File lib/rss/taxonomy.rb, line 108
def required_uri
  TAXO_URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/taxonomy.rb, line 128
def full_name
  tag_name_with_prefix(TAXO_PREFIX)
end
maker_target(target) click to toggle source
# File lib/rss/taxonomy.rb, line 132
def maker_target(target)
  target.new_taxo_topic
end


module RSS::TaxonomyTopicsModel - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::TaxonomyTopicsModel

In Files

  • lib/rss/taxonomy.rb

Public Class Methods

append_features(klass) click to toggle source
# File lib/rss/taxonomy.rb, line 28
def self.append_features(klass)
  super

  klass.install_must_call_validator(TAXO_PREFIX, TAXO_URI)
  %w(topics).each do |name|
    klass.install_have_child_element(name, TAXO_URI, "?",
                                     "#{TAXO_PREFIX}_#{name}")
  end
end


class RSS::TaxonomyTopicsModel::TaxonomyTopics - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::TaxonomyTopicsModel::TaxonomyTopics

In Files

  • lib/rss/taxonomy.rb

Parent

RSS::Element

Included Modules

  • RSS::RSS10

Constants

Bag

Public Class Methods

new(*args) click to toggle source
# File lib/rss/taxonomy.rb, line 58
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.Bag = args[0]
  end
  self.Bag ||= Bag.new
end
required_prefix() click to toggle source
# File lib/rss/taxonomy.rb, line 44
def required_prefix
  TAXO_PREFIX
end
required_uri() click to toggle source
# File lib/rss/taxonomy.rb, line 48
def required_uri
  TAXO_URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/taxonomy.rb, line 68
def full_name
  tag_name_with_prefix(TAXO_PREFIX)
end
maker_target(target) click to toggle source
# File lib/rss/taxonomy.rb, line 72
def maker_target(target)
  target.taxo_topics
end
resources() click to toggle source
# File lib/rss/taxonomy.rb, line 76
def resources
  if @Bag
    @Bag.lis.collect do |li|
      li.resource
    end
  else
    []
  end
end


class RSS::TooMuchTagError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::TooMuchTagError

Raised if there are more occurrences of the tag than expected.

In Files

  • lib/rss/rss.rb

Parent

RSS::InvalidRSSError

Attributes

parent[R]
tag[R]

Public Class Methods

new(tag, parent) click to toggle source
# File lib/rss/rss.rb, line 89
def initialize(tag, parent)
  @tag, @parent = tag, parent
  super("tag <#{tag}> is too much in tag <#{parent}>")
end


module RSS::TrackBackModel10 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::TrackBackModel10

In Files

  • lib/rss/trackback.rb


class RSS::TrackBackModel10::TrackBackAbout - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::TrackBackModel10::TrackBackAbout

In Files

  • lib/rss/trackback.rb

Parent

RSS::Element

Included Modules

  • RSS::RSS10

Public Class Methods

new(*args) click to toggle source
# File lib/rss/trackback.rb, line 167
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.resource = args[0]
  end
end
required_prefix() click to toggle source
# File lib/rss/trackback.rb, line 145
def required_prefix
  TRACKBACK_PREFIX
end
required_uri() click to toggle source
# File lib/rss/trackback.rb, line 149
def required_uri
  TRACKBACK_URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/trackback.rb, line 176
def full_name
  tag_name_with_prefix(TRACKBACK_PREFIX)
end


class RSS::TrackBackModel10::TrackBackPing - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::TrackBackModel10::TrackBackPing

In Files

  • lib/rss/trackback.rb

Parent

RSS::Element

Included Modules

  • RSS::RSS10

Public Class Methods

new(*args) click to toggle source
# File lib/rss/trackback.rb, line 126
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.resource = args[0]
  end
end
required_prefix() click to toggle source
# File lib/rss/trackback.rb, line 105
def required_prefix
  TRACKBACK_PREFIX
end
required_uri() click to toggle source
# File lib/rss/trackback.rb, line 109
def required_uri
  TRACKBACK_URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/trackback.rb, line 135
def full_name
  tag_name_with_prefix(TRACKBACK_PREFIX)
end


module RSS::TrackBackModel20 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::TrackBackModel20

In Files

  • lib/rss/trackback.rb


class RSS::TrackBackModel20::TrackBackAbout - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::TrackBackModel20::TrackBackAbout

In Files

  • lib/rss/trackback.rb

Parent

RSS::Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/trackback.rb, line 255
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.content = args[0]
  end
end
required_prefix() click to toggle source
# File lib/rss/trackback.rb, line 242
def required_prefix
  TRACKBACK_PREFIX
end
required_uri() click to toggle source
# File lib/rss/trackback.rb, line 246
def required_uri
  TRACKBACK_URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/trackback.rb, line 264
def full_name
  tag_name_with_prefix(TRACKBACK_PREFIX)
end


class RSS::TrackBackModel20::TrackBackPing - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::TrackBackModel20::TrackBackPing

In Files

  • lib/rss/trackback.rb

Parent

RSS::Element

Included Modules

  • RSS::RSS09

Public Class Methods

new(*args) click to toggle source
# File lib/rss/trackback.rb, line 218
def initialize(*args)
  if Utils.element_initialize_arguments?(args)
    super
  else
    super()
    self.content = args[0]
  end
end
required_prefix() click to toggle source
# File lib/rss/trackback.rb, line 205
def required_prefix
  TRACKBACK_PREFIX
end
required_uri() click to toggle source
# File lib/rss/trackback.rb, line 209
def required_uri
  TRACKBACK_URI
end

Public Instance Methods

full_name() click to toggle source
# File lib/rss/trackback.rb, line 227
def full_name
  tag_name_with_prefix(TRACKBACK_PREFIX)
end


module RSS::TrackBackUtils - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::TrackBackUtils

In Files

  • lib/rss/trackback.rb


class RSS::UnknownConvertMethod - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::UnknownConvertMethod

Raised when an unknown conversion error occurs.

In Files

  • lib/rss/rss.rb

Parent

RSS::Error

Attributes

from[R]
to[R]

Public Class Methods

new(to, from) click to toggle source
# File lib/rss/rss.rb, line 149
def initialize(to, from)
  @to = to
  @from = from
  super("can't convert to #{to} from #{from}.")
end


class RSS::UnknownTagError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::UnknownTagError

Raised when an unknown tag is found.

In Files

  • lib/rss/rss.rb

Parent

RSS::InvalidRSSError

Attributes

tag[R]
uri[R]

Public Class Methods

new(tag, uri) click to toggle source
# File lib/rss/rss.rb, line 111
def initialize(tag, uri)
  @tag, @uri = tag, uri
  super("tag <#{tag}> is unknown in namespace specified by uri <#{uri}>")
end


class RSS::UnsupportedMakerVersionError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::UnsupportedMakerVersionError

Raised when a RSS::Maker attempts to use an unknown maker.

In Files

  • lib/rss/rss.rb

Parent

RSS::Error

Attributes

version[R]

Public Class Methods

new(version) click to toggle source
# File lib/rss/rss.rb, line 188
def initialize(version)
  @version = version
  super("Maker doesn't support version: #{@version}")
end


module RSS::Utils - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Utils

In Files

  • lib/rss/utils.rb

Public Instance Methods

element_initialize_arguments?(args) click to toggle source
# File lib/rss/utils.rb, line 35
def element_initialize_arguments?(args)
  [true, false].include?(args[0]) and args[1].is_a?(Hash)
end
get_file_and_line_from_caller(i=0) click to toggle source
# File lib/rss/utils.rb, line 12
def get_file_and_line_from_caller(i=0)
  file, line, = caller[i].split(':')
  line = line.to_i
  line += 1 if i.zero?
  [file, line]
end
h(s) click to toggle source
Alias for: html_escape
html_escape(s) click to toggle source

escape '&', '“', '<' and '>' for use in HTML.

# File lib/rss/utils.rb, line 20
def html_escape(s)
  s.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
end
Also aliased as: h
new_with_value_if_need(klass, value) click to toggle source

If value is an instance of class klass, return it, else create a new instance of klass with value value.

# File lib/rss/utils.rb, line 27
def new_with_value_if_need(klass, value)
  if value.is_a?(klass)
    value
  else
    klass.new(value)
  end
end
to_class_name(name) click to toggle source

Convert a name_with_underscores to CamelCase.

# File lib/rss/utils.rb, line 6
def to_class_name(name)
  name.split(/[_\-]/).collect do |part|
    "#{part[0, 1].upcase}#{part[1..-1]}"
  end.join("")
end


module RSS::Utils::CSV - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Utils::CSV

In Files

  • lib/rss/utils.rb

Public Instance Methods

parse(value, &block) click to toggle source
# File lib/rss/utils.rb, line 70
def parse(value, &block)
  if value.is_a?(String)
    value = value.strip.split(/\s*,\s*/)
    value = value.collect(&block) if block_given?
    value
  else
    value
  end
end


module RSS::Utils::InheritedReader - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Utils::InheritedReader

In Files

  • lib/rss/utils.rb

Public Instance Methods

inherited_array_reader(constant_name) click to toggle source
# File lib/rss/utils.rb, line 98
def inherited_array_reader(constant_name)
  inherited_reader(constant_name) do |result, current|
    current + result
  end
end
inherited_hash_reader(constant_name) click to toggle source
# File lib/rss/utils.rb, line 104
def inherited_hash_reader(constant_name)
  inherited_reader(constant_name) do |result, current|
    result.merge(current)
  end
end
inherited_reader(constant_name) { |result, const| ... } click to toggle source
# File lib/rss/utils.rb, line 82
def inherited_reader(constant_name)
  base_class = inherited_base
  result = base_class.const_get(constant_name)
  found_base_class = false
  ancestors.reverse_each do |klass|
    if found_base_class
      if klass.const_defined?(constant_name)
        result = yield(result, klass.const_get(constant_name))
      end
    else
      found_base_class = klass == base_class
    end
  end
  result
end


module RSS::Utils::YesCleanOther - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Utils::YesCleanOther

In Files

  • lib/rss/utils.rb

Public Instance Methods

parse(value) click to toggle source
# File lib/rss/utils.rb, line 41
def parse(value)
  if [true, false, nil].include?(value)
    value
  else
    case value.to_s
    when /\Ayes\z/
      true
    when /\Aclean\z/
      false
    else
      nil
    end
  end
end


module RSS::Utils::YesOther - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::Utils::YesOther

In Files

  • lib/rss/utils.rb

Public Instance Methods

parse(value) click to toggle source
# File lib/rss/utils.rb, line 59
def parse(value)
  if [true, false].include?(value)
    value
  else
    /\Ayes\z/.match(value.to_s) ? true : false
  end
end


module RSS::XML - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::XML

In Files

  • lib/rss/xml.rb


class RSS::XML::Element - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::XML::Element

In Files

  • lib/rss/xml.rb

Parent

Object

Included Modules

  • Enumerable

Attributes

attributes[R]
children[R]
name[R]
prefix[R]
uri[R]

Public Class Methods

new(name, prefix=nil, uri=nil, attributes={}, children=[]) click to toggle source
# File lib/rss/xml.rb, line 9
def initialize(name, prefix=nil, uri=nil, attributes={}, children=[])
  @name = name
  @prefix = prefix
  @uri = uri
  @attributes = attributes
  if children.is_a?(String) or !children.respond_to?(:each)
    @children = [children]
  else
    @children = children
  end
end

Public Instance Methods

<<(child) click to toggle source
# File lib/rss/xml.rb, line 29
def <<(child)
  @children << child
end
==(other) click to toggle source
# File lib/rss/xml.rb, line 37
def ==(other)
  other.kind_of?(self.class) and
    @name == other.name and
    @uri == other.uri and
    @attributes == other.attributes and
    @children == other.children
end
[](name) click to toggle source
# File lib/rss/xml.rb, line 21
def [](name)
  @attributes[name]
end
[]=(name, value) click to toggle source
# File lib/rss/xml.rb, line 25
def []=(name, value)
  @attributes[name] = value
end
each(&block) click to toggle source
# File lib/rss/xml.rb, line 33
def each(&block)
  @children.each(&block)
end
full_name() click to toggle source
# File lib/rss/xml.rb, line 62
def full_name
  if @prefix
    "#{@prefix}:#{@name}"
  else
    @name
  end
end
to_s() click to toggle source
# File lib/rss/xml.rb, line 45
def to_s
  rv = "<#{full_name}"
  attributes.each do |key, value|
    rv << " #{Utils.html_escape(key)}=\"#{Utils.html_escape(value)}\""
  end
  if children.empty?
    rv << "/>"
  else
    rv << ">"
    children.each do |child|
      rv << child.to_s
    end
    rv << "</#{full_name}>"
  end
  rv
end


class RSS::XMLParserListener - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::XMLParserListener

In Files

  • lib/rss/xmlparser.rb

Parent

RSS::BaseListener

Included Modules

  • RSS::ListenerMixin

Public Instance Methods

xmldecl(version, encoding, standalone) click to toggle source
# File lib/rss/xmlparser.rb, line 85
def xmldecl(version, encoding, standalone)
  super
  # Encoding is converted to UTF-8 when XMLParser parses XML.
  @encoding = 'UTF-8'
end


class RSS::XMLParserNotFound - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::XMLParserNotFound

In Files

  • lib/rss/parser.rb

Parent

Error

Public Class Methods

new() click to toggle source
# File lib/rss/parser.rb, line 28
def initialize
  super("available XML parser was not found in " <<
        "#{AVAILABLE_PARSER_LIBRARIES.inspect}.")
end


class RSS::XMLParserParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::XMLParserParser

In Files

  • lib/rss/xmlparser.rb

Parent

RSS::BaseParser

Public Class Methods

listener() click to toggle source
# File lib/rss/xmlparser.rb, line 63
def listener
  XMLParserListener
end


class RSS::XMLScanListener - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::XMLScanListener

In Files

  • lib/rss/xmlscanner.rb

Parent

RSS::BaseListener

Included Modules

  • XMLScan::Visitor
  • RSS::ListenerMixin

Constants

ENTITIES

Public Instance Methods

on_attr_charref(code) click to toggle source
# File lib/rss/xmlscanner.rb, line 95
def on_attr_charref(code)
  @current_attr << [code].pack('U')
end
Also aliased as: on_attr_charref_hex
on_attr_charref_hex(code) click to toggle source
Alias for: on_attr_charref
on_attr_entityref(ref) click to toggle source
# File lib/rss/xmlscanner.rb, line 91
def on_attr_entityref(ref)
  @current_attr << entity(ref)
end
on_attr_value(str) click to toggle source
# File lib/rss/xmlscanner.rb, line 87
def on_attr_value(str)
  @current_attr << str
end
on_attribute(name) click to toggle source
# File lib/rss/xmlscanner.rb, line 83
def on_attribute(name)
  @attrs[name] = @current_attr = ''
end
on_charref(code) click to toggle source
# File lib/rss/xmlscanner.rb, line 73
def on_charref(code)
  text([code].pack('U'))
end
Also aliased as: on_charref_hex
on_charref_hex(code) click to toggle source
Alias for: on_charref
on_entityref(ref) click to toggle source
# File lib/rss/xmlscanner.rb, line 69
def on_entityref(ref)
  text(entity(ref))
end
on_etag(name) click to toggle source
# File lib/rss/xmlscanner.rb, line 65
def on_etag(name)
  tag_end(name)
end
on_stag(name) click to toggle source
# File lib/rss/xmlscanner.rb, line 79
def on_stag(name)
  @attrs = {}
end
on_stag_end(name) click to toggle source
# File lib/rss/xmlscanner.rb, line 101
def on_stag_end(name)
  tag_start(name, @attrs)
end
on_stag_end_empty(name) click to toggle source
# File lib/rss/xmlscanner.rb, line 105
def on_stag_end_empty(name)
  tag_start(name, @attrs)
  tag_end(name)
end
on_xmldecl_encoding(str) click to toggle source
# File lib/rss/xmlscanner.rb, line 49
def on_xmldecl_encoding(str)
  @encoding = str
end
on_xmldecl_end() click to toggle source
# File lib/rss/xmlscanner.rb, line 57
def on_xmldecl_end
  xmldecl(@version, @encoding, @standalone == "yes")
end
on_xmldecl_standalone(str) click to toggle source
# File lib/rss/xmlscanner.rb, line 53
def on_xmldecl_standalone(str)
  @standalone = str
end
on_xmldecl_version(str) click to toggle source
# File lib/rss/xmlscanner.rb, line 45
def on_xmldecl_version(str)
  @version = str
end


class RSS::XMLScanParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::XMLScanParser

In Files

  • lib/rss/xmlscanner.rb

Parent

RSS::BaseParser

Public Class Methods

listener() click to toggle source
# File lib/rss/xmlscanner.rb, line 9
def listener
  XMLScanListener
end


class RSS::XMLStyleSheet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RSS::XMLStyleSheet

In Files

  • lib/rss/xml-stylesheet.rb

Parent

Object

Included Modules

  • RSS::Utils

Constants

ATTRIBUTES
GUESS_TABLE

Attributes

do_validate[RW]

Public Class Methods

new(*attrs) click to toggle source
# File lib/rss/xml-stylesheet.rb, line 37
def initialize(*attrs)
  if attrs.size == 1 and
      (attrs.first.is_a?(Hash) or attrs.first.is_a?(Array))
    attrs = attrs.first
  end
  @do_validate = true
  ATTRIBUTES.each do |attr|
    __send__("#{attr}=", nil)
  end
  vars = ATTRIBUTES.dup
  vars.unshift(:do_validate)
  attrs.each do |name, value|
    if vars.include?(name.to_s)
      __send__("#{name}=", value)
    end
  end
end

Public Instance Methods

alternate=(value) click to toggle source
# File lib/rss/xml-stylesheet.rb, line 79
def alternate=(value)
  if value.nil? or /\A(?:yes|no)\z/ =~ value
    @alternate = value
  else
    if @do_validate
      args = ["?xml-stylesheet?", %Q[alternate="#{value}"]]
      raise NotAvailableValueError.new(*args)
    end
  end
  @alternate
end
href=(value) click to toggle source
# File lib/rss/xml-stylesheet.rb, line 70
def href=(value)
  @href = value
  if @href and @type.nil?
    @type = guess_type(@href)
  end
  @href
end
setup_maker(maker) click to toggle source
# File lib/rss/xml-stylesheet.rb, line 91
def setup_maker(maker)
  xss = maker.xml_stylesheets.new_xml_stylesheet
  ATTRIBUTES.each do |attr|
    xss.__send__("#{attr}=", __send__(attr))
  end
end
to_s() click to toggle source
# File lib/rss/xml-stylesheet.rb, line 55
def to_s
  rv = ""
  if @href
    rv << %Q[<?xml-stylesheet]
    ATTRIBUTES.each do |name|
      if __send__(name)
        rv << %Q[ #{name}="#{h __send__(name)}"]
      end
    end
    rv << %Q[?>]
  end
  rv
end


module RSS::XMLStyleSheetMixin - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RSS::XMLStyleSheetMixin

In Files

  • lib/rss/xml-stylesheet.rb

Attributes

xml_stylesheets[RW]

Public Class Methods

new(*args) click to toggle source
# File lib/rss/xml-stylesheet.rb, line 7
def initialize(*args)
  super
  @xml_stylesheets = []
end


module Racc - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Racc

Racc is a LALR(1) parser generator. It is written in Ruby itself, and generates Ruby programs.

Command-line Reference

racc [-o<var>filename</var>] [--output-file=<var>filename</var>]
     [-e<var>rubypath</var>] [--embedded=<var>rubypath</var>]
     [-v] [--verbose]
     [-O<var>filename</var>] [--log-file=<var>filename</var>]
     [-g] [--debug]
     [-E] [--embedded]
     [-l] [--no-line-convert]
     [-c] [--line-convert-all]
     [-a] [--no-omit-actions]
     [-C] [--check-only]
     [-S] [--output-status]
     [--version] [--copyright] [--help] <var>grammarfile</var>
filename

Racc grammar file. Any extention is permitted.

-o+outfile+, –output-file=outfile

A filename for output. default is <filename>.tab.rb

-O+filename+, –log-file=filename

Place logging output in file filename. Default log file name is <filename>.output.

-e+rubypath+, –executable=rubypath

output executable file(mode 755). where path is the ruby interpreter.

-v, –verbose

verbose mode. create filename.output file, like yacc's y.output file.

-g, –debug

add debug code to parser class. To display debuggin information, use this '-g' option and set @yydebug true in parser class.

-E, –embedded

Output parser which doesn't need runtime files (racc/parser.rb).

-C, –check-only

Check syntax of racc grammer file and quit.

-S, –output-status

Print messages time to time while compiling.

-l, –no-line-convert

turns off line number converting.

-c, –line-convert-all

Convert line number of actions, inner, header and footer.

-a, –no-omit-actions

Call all actions, even if an action is empty.

–version

print Racc version and quit.

–copyright

Print copyright and quit.

–help

Print usage and quit.

Generating Parser Using Racc

To compile Racc grammar file, simply type:

$ racc parse.y

This creates ruby script file “parse.tab.y”. The -o option can change the output filename.

Writing A Racc Grammar File

If you want your own parser, you have to write a grammar file. A grammar file contains the name of your parser class, grammar for the parser, user code, and anything else. When writing a grammar file, yacc's knowledge is helpful. If you have not used yacc before, Racc is not too difficult.

Here's an example Racc grammar file.

class Calcparser
rule
  target: exp { print val[0] }

  exp: exp '+' exp
     | exp '*' exp
     | '(' exp ')'
     | NUMBER
end

Racc grammar files resemble yacc files. But (of course), this is Ruby code. yacc's $$ is the 'result', $0, $1… is an array called 'val', and $-1, $-2… is an array called '_values'.

See the Grammar File Reference for more information on grammar files.

Parser

Then you must prepare the parse entry method. There are two types of parse methods in Racc, Racc::Parser#do_parse and Racc::Parser#yyparse

Racc::Parser#do_parse is simple.

It's yyparse() of yacc, and Racc::Parser#next_token is yylex(). This method must returns an array like [TOKENSYMBOL, ITS_VALUE]. EOF is [false, false]. (TOKENSYMBOL is a Ruby symbol (taken from String#intern) by default. If you want to change this, see the grammar reference.

Racc::Parser#yyparse is little complicated, but useful. It does not use Racc::Parser#next_token, instead it gets tokens from any iterator.

For example, yyparse(obj, :scan) causes calling +objscan+, and you can return tokens by yielding them from +objscan+.

Debugging

When debugging, “-v” or/and the “-g” option is helpful.

“-v” creates verbose log file (.output). “-g” creates a “Verbose Parser”. Verbose Parser prints the internal status when parsing. But it's not automatic. You must use -g option and set +@yydebug+ to true in order to get output. -g option only creates the verbose parser.

Racc reported syntax error.

Isn't there too many “end”? grammar of racc file is changed in v0.10.

Racc does not use '%' mark, while yacc uses huge number of '%' marks..

Racc reported “XXXX conflicts”.

Try “racc -v xxxx.y”. It causes producing racc's internal log file, xxxx.output.

Generated parsers does not work correctly

Try “racc -g xxxx.y”. This command let racc generate “debugging parser”. Then set @yydebug=true in your parser. It produces a working log of your parser.

Re-distributing Racc runtime

A parser, which is created by Racc, requires the Racc runtime module; racc/parser.rb.

Ruby 1.8.x comes with Racc runtime module, you need NOT distribute Racc runtime files.

If you want to include the Racc runtime module with your parser. This can be done by using '-E' option:

$ racc -E -omyparser.rb myparser.y

This command creates myparser.rb which `includes' Racc runtime. Only you must do is to distribute your parser file (myparser.rb).

Note: parser.rb is LGPL, but your parser is not. Your own parser is completely yours.

In Files

  • lib/racc/parser.rb
  • ext/racc/cparse/cparse.c


class Racc::CparseParams - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Racc::CparseParams

In Files

  • ext/racc/cparse/cparse.c

Parent

Object


class Racc::Parser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Racc::Parser

In Files

  • lib/racc/parser.rb
  • ext/racc/cparse/cparse.c

Parent

Object

Constants

Racc_Runtime_Core_Id_C
Racc_Runtime_Core_Revision_C

Racc_Runtime_Core_Version_C = (defined in extention)

Racc_Runtime_Core_Revision_R
Racc_Runtime_Core_Version_C
Racc_Runtime_Core_Version_R
Racc_Runtime_Revision
Racc_Runtime_Version

Public Instance Methods

_racc_do_parse_rb(arg, in_debug) click to toggle source
# File lib/racc/parser.rb, line 273
def _racc_do_parse_rb(arg, in_debug)
  action_table, action_check, action_default, action_pointer,
  _,            _,            _,              _,
  _,            _,            token_table,    _,
  _,            _,            * = arg

  _racc_init_sysvars
  tok = act = i = nil

  catch(:racc_end_parse) {
    while true
      if i = action_pointer[@racc_state[-1]]
        if @racc_read_next
          if @racc_t != 0   # not EOF
            tok, @racc_val = next_token()
            unless tok      # EOF
              @racc_t = 0
            else
              @racc_t = (token_table[tok] or 1)   # error token
            end
            racc_read_token(@racc_t, tok, @racc_val) if @yydebug
            @racc_read_next = false
          end
        end
        i += @racc_t
        unless i >= 0 and
               act = action_table[i] and
               action_check[i] == @racc_state[-1]
          act = action_default[@racc_state[-1]]
        end
      else
        act = action_default[@racc_state[-1]]
      end
      while act = _racc_evalact(act, arg)
        ;
      end
    end
  }
end
_racc_do_reduce(arg, act) click to toggle source
# File lib/racc/parser.rb, line 473
def _racc_do_reduce(arg, act)
  _, _, _, _,
  goto_table,   goto_check,   goto_default,   goto_pointer,
  nt_base,      reduce_table, _,    _,
  _,     use_result,   * = arg
  state = @racc_state
  vstack = @racc_vstack
  tstack = @racc_tstack

  i = act * -3
  len       = reduce_table[i]
  reduce_to = reduce_table[i+1]
  method_id = reduce_table[i+2]
  void_array = []

  tmp_t = tstack[-len, len] if @yydebug
  tmp_v = vstack[-len, len]
  tstack[-len, len] = void_array if @yydebug
  vstack[-len, len] = void_array
  state[-len, len]  = void_array

  # tstack must be updated AFTER method call
  if use_result
    vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
  else
    vstack.push __send__(method_id, tmp_v, vstack)
  end
  tstack.push reduce_to

  racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug

  k1 = reduce_to - nt_base
  if i = goto_pointer[k1]
    i += state[-1]
    if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
      return curstate
    end
  end
  goto_default[k1]
end
_racc_evalact(act, arg) click to toggle source

common

# File lib/racc/parser.rb, line 378
def _racc_evalact(act, arg)
  action_table, action_check, _, action_pointer,
  _,   _, _, _,
  _,   _, _, shift_n,  reduce_n,
  _,   _, * = arg
  nerr = 0   # tmp

  if act > 0 and act < shift_n
    #
    # shift
    #
    if @racc_error_status > 0
      @racc_error_status -= 1 unless @racc_t == 1   # error token
    end
    @racc_vstack.push @racc_val
    @racc_state.push act
    @racc_read_next = true
    if @yydebug
      @racc_tstack.push @racc_t
      racc_shift @racc_t, @racc_tstack, @racc_vstack
    end

  elsif act < 0 and act > -reduce_n
    #
    # reduce
    #
    code = catch(:racc_jump) {
      @racc_state.push _racc_do_reduce(arg, act)
      false
    }
    if code
      case code
      when 1 # yyerror
        @racc_user_yyerror = true   # user_yyerror
        return -reduce_n
      when 2 # yyaccept
        return shift_n
      else
        raise '[Racc Bug] unknown jump code'
      end
    end

  elsif act == shift_n
    #
    # accept
    #
    racc_accept if @yydebug
    throw :racc_end_parse, @racc_vstack[0]

  elsif act == -reduce_n
    #
    # error
    #
    case @racc_error_status
    when 0
      unless arg[21]    # user_yyerror
        nerr += 1
        on_error @racc_t, @racc_val, @racc_vstack
      end
    when 3
      if @racc_t == 0   # is $
        throw :racc_end_parse, nil
      end
      @racc_read_next = true
    end
    @racc_user_yyerror = false
    @racc_error_status = 3
    while true
      if i = action_pointer[@racc_state[-1]]
        i += 1   # error token
        if  i >= 0 and
            (act = action_table[i]) and
            action_check[i] == @racc_state[-1]
          break
        end
      end
      throw :racc_end_parse, nil if @racc_state.size <= 1
      @racc_state.pop
      @racc_vstack.pop
      if @yydebug
        @racc_tstack.pop
        racc_e_pop @racc_state, @racc_tstack, @racc_vstack
      end
    end
    return act

  else
    raise "[Racc Bug] unknown action #{act.inspect}"
  end

  racc_next_state(@racc_state[-1], @racc_state) if @yydebug

  nil
end
_racc_init_sysvars() click to toggle source
# File lib/racc/parser.rb, line 228
def _racc_init_sysvars
  @racc_state  = [0]
  @racc_tstack = []
  @racc_vstack = []

  @racc_t = nil
  @racc_val = nil

  @racc_read_next = true

  @racc_user_yyerror = false
  @racc_error_status = 0
end
_racc_setup() click to toggle source
# File lib/racc/parser.rb, line 216
def _racc_setup
  @yydebug = false unless self.class::Racc_debug_parser
  @yydebug = false unless defined?(@yydebug)
  if @yydebug
    @racc_debug_out = $stderr unless defined?(@racc_debug_out)
    @racc_debug_out ||= $stderr
  end
  arg = self.class::Racc_arg
  arg[13] = true if arg.size < 14
  arg
end
_racc_yyparse_rb(recv, mid, arg, c_debug) click to toggle source
# File lib/racc/parser.rb, line 322
def _racc_yyparse_rb(recv, mid, arg, c_debug)
  action_table, action_check, action_default, action_pointer,
  _,             _,            _,              _,
  _,            _,            token_table,    _,
  _,            _,            * = arg

  _racc_init_sysvars
  act = nil
  i = nil

  catch(:racc_end_parse) {
    until i = action_pointer[@racc_state[-1]]
      while act = _racc_evalact(action_default[@racc_state[-1]], arg)
        ;
      end
    end
    recv.__send__(mid) do |tok, val|
      unless tok
        @racc_t = 0
      else
        @racc_t = (token_table[tok] or 1)   # error token
      end
      @racc_val = val
      @racc_read_next = false

      i += @racc_t
      unless i >= 0 and
             act = action_table[i] and
             action_check[i] == @racc_state[-1]
        act = action_default[@racc_state[-1]]
      end
      while act = _racc_evalact(act, arg)
        ;
      end

      while not(i = action_pointer[@racc_state[-1]]) or
            not @racc_read_next or
            @racc_t == 0   # $
        unless i and i += @racc_t and
               i >= 0 and
               act = action_table[i] and
               action_check[i] == @racc_state[-1]
          act = action_default[@racc_state[-1]]
        end
        while act = _racc_evalact(act, arg)
          ;
        end
      end
    end
  }
end
do_parse() click to toggle source

The entry point of the parser. This method is used with next_token. If Racc wants to get token (and its value), calls next_token.

Example:

def parse
  @q = [[1,1],
        [2,2],
        [3,3],
        [false, '$']]
  do_parse
end

def next_token
  @q.shift
end

# File lib/racc/parser.rb, line 257
def do_parse
  __send__(Racc_Main_Parsing_Routine, _racc_setup(), false)
end
next_token() click to toggle source

The method to fetch next token. If you use do_parse method, you must implement next_token.

The format of return value is [TOKEN_SYMBOL, VALUE]. token-symbol is represented by Ruby's symbol by default, e.g. :IDENT for 'IDENT'. “;” (String) for ';'.

The final symbol (End of file) must be false.

# File lib/racc/parser.rb, line 269
def next_token
  raise NotImplementedError, "#{self.class}\#next_token is not defined"
end
on_error(t, val, vstack) click to toggle source

This method is called when a parse error is found.

ERROR_TOKEN_ID is an internal ID of token which caused error. You can get string representation of this ID by calling token_to_str.

ERROR_VALUE is a value of error token.

value_stack is a stack of symbol values. DO NOT MODIFY this object.

This method raises ParseError by default.

If this method returns, parsers enter “error recovering mode”.

# File lib/racc/parser.rb, line 528
def on_error(t, val, vstack)
  raise ParseError, sprintf("\nparse error on value %s (%s)",
                            val.inspect, token_to_str(t) || '?')
end
racc_accept() click to toggle source
# File lib/racc/parser.rb, line 578
def racc_accept
  @racc_debug_out.puts 'accept'
  @racc_debug_out.puts
end
racc_e_pop(state, tstack, vstack) click to toggle source
# File lib/racc/parser.rb, line 583
def racc_e_pop(state, tstack, vstack)
  @racc_debug_out.puts 'error recovering mode: pop token'
  racc_print_states state
  racc_print_stacks tstack, vstack
  @racc_debug_out.puts
end
racc_next_state(curstate, state) click to toggle source
# File lib/racc/parser.rb, line 590
def racc_next_state(curstate, state)
  @racc_debug_out.puts  "goto    #{curstate}"
  racc_print_states state
  @racc_debug_out.puts
end
racc_print_stacks(t, v) click to toggle source
# File lib/racc/parser.rb, line 596
def racc_print_stacks(t, v)
  out = @racc_debug_out
  out.print '        ['
  t.each_index do |i|
    out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
  end
  out.puts ' ]'
end
racc_print_states(s) click to toggle source
# File lib/racc/parser.rb, line 605
def racc_print_states(s)
  out = @racc_debug_out
  out.print '        ['
  s.each {|st| out.print ' ', st }
  out.puts ' ]'
end
racc_read_token(t, tok, val) click to toggle source

For debugging output

# File lib/racc/parser.rb, line 551
def racc_read_token(t, tok, val)
  @racc_debug_out.print 'read    '
  @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
  @racc_debug_out.puts val.inspect
  @racc_debug_out.puts
end
racc_reduce(toks, sim, tstack, vstack) click to toggle source
# File lib/racc/parser.rb, line 564
def racc_reduce(toks, sim, tstack, vstack)
  out = @racc_debug_out
  out.print 'reduce '
  if toks.empty?
    out.print ' <none>'
  else
    toks.each {|t| out.print ' ', racc_token2str(t) }
  end
  out.puts " --> #{racc_token2str(sim)}"

  racc_print_stacks tstack, vstack
  @racc_debug_out.puts
end
racc_shift(tok, tstack, vstack) click to toggle source
# File lib/racc/parser.rb, line 558
def racc_shift(tok, tstack, vstack)
  @racc_debug_out.puts "shift   #{racc_token2str tok}"
  racc_print_stacks tstack, vstack
  @racc_debug_out.puts
end
racc_token2str(tok) click to toggle source
# File lib/racc/parser.rb, line 612
def racc_token2str(tok)
  self.class::Racc_token_to_s_table[tok] or
      raise "[Racc Bug] can't convert token #{tok} to string"
end
token_to_str(t) click to toggle source

Convert internal ID of token symbol to the string.

# File lib/racc/parser.rb, line 618
def token_to_str(t)
  self.class::Racc_token_to_s_table[t]
end
yyaccept() click to toggle source

Exit parser. Return value is Symbol_Value_Stack.

# File lib/racc/parser.rb, line 541
def yyaccept
  throw :racc_jump, 2
end
yyerrok() click to toggle source

Leave error recovering mode.

# File lib/racc/parser.rb, line 546
def yyerrok
  @racc_error_status = 0
end
yyerror() click to toggle source

Enter error recovering mode. This method does not call on_error.

# File lib/racc/parser.rb, line 535
def yyerror
  throw :racc_jump, 1
end
yyparse(recv, mid) click to toggle source

Another entry point for the parser. If you use this method, you must implement RECEIVER#METHOD_ID method.

RECEIVER#METHOD_ID is a method to get next token. It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].

# File lib/racc/parser.rb, line 318
def yyparse(recv, mid)
  __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), true)
end


module Rake - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake

In Files

  • lib/rake/application.rb
  • lib/rake/backtrace.rb
  • lib/rake/cloneable.rb
  • lib/rake/contrib/compositepublisher.rb
  • lib/rake/contrib/ftptools.rb
  • lib/rake/contrib/rubyforgepublisher.rb
  • lib/rake/contrib/sshpublisher.rb
  • lib/rake/default_loader.rb
  • lib/rake/dsl_definition.rb
  • lib/rake/early_time.rb
  • lib/rake/file_creation_task.rb
  • lib/rake/file_list.rb
  • lib/rake/file_task.rb
  • lib/rake/file_utils_ext.rb
  • lib/rake/gempackagetask.rb
  • lib/rake/invocation_chain.rb
  • lib/rake/invocation_exception_mixin.rb
  • lib/rake/loaders/makefile.rb
  • lib/rake/multi_task.rb
  • lib/rake/name_space.rb
  • lib/rake/packagetask.rb
  • lib/rake/private_reader.rb
  • lib/rake/promise.rb
  • lib/rake/pseudo_status.rb
  • lib/rake/rake_module.rb
  • lib/rake/rdoctask.rb
  • lib/rake/rule_recursion_overflow_error.rb
  • lib/rake/runtest.rb
  • lib/rake/task.rb
  • lib/rake/tasklib.rb
  • lib/rake/task_arguments.rb
  • lib/rake/task_argument_error.rb
  • lib/rake/task_manager.rb
  • lib/rake/testtask.rb
  • lib/rake/thread_history_display.rb
  • lib/rake/thread_pool.rb
  • lib/rake/trace_output.rb
  • lib/rake/version.rb
  • lib/rake/win32.rb

Included Modules

  • Test::Unit::Assertions

Constants

CommandLineOptionError
DeprecatedCommands
EARLY
EMPTY_TASK_ARGS
VERSION

Public Class Methods

add_rakelib(*files) click to toggle source

Add files to the rakelib list

# File lib/rake/rake_module.rb, line 29
def add_rakelib(*files)
  application.options.rakelib ||= []
  files.each do |file|
    application.options.rakelib << file
  end
end
application() click to toggle source

Current Rake Application

# File lib/rake/rake_module.rb, line 9
def application
  @application ||= Rake::Application.new
end
application=(app) click to toggle source

Set the current Rake application object.

# File lib/rake/rake_module.rb, line 14
def application=(app)
  @application = app
end
load_rakefile(path) click to toggle source

Load a rakefile.

# File lib/rake/rake_module.rb, line 24
def load_rakefile(path)
  load(path)
end
original_dir() click to toggle source

Return the original directory where the Rake application was started.

# File lib/rake/rake_module.rb, line 19
def original_dir
  application.original_dir
end

Public Instance Methods

run_tests(pattern='test/test*.rb', log_enabled=false) click to toggle source
# File lib/rake/runtest.rb, line 8
def run_tests(pattern='test/test*.rb', log_enabled=false)
  FileList.glob(pattern).each { |fn|
    $stderr.puts fn if log_enabled
    begin
      require fn
    rescue Exception => ex
      $stderr.puts "Error in #{fn}: #{ex.message}"
      $stderr.puts ex.backtrace
      assert false
    end
  }
end


module Rake::AltSystem - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake::AltSystem

Alternate implementations of system() and backticks “ on Windows for ruby-1.8 and earlier.

In Files

  • lib/rake/alt_system.rb

Constants

RUNNABLE_EXTS
RUNNABLE_PATTERN
WINDOWS

Public Class Methods

define_module_function(name, &block) click to toggle source
# File lib/rake/alt_system.rb, line 36
def define_module_function(name, &block)
  define_method(name, &block)
  module_function(name)
end

Public Instance Methods

backticks(cmd) click to toggle source
# File lib/rake/alt_system.rb, line 98
def backticks(cmd)
  kernel_backticks(repair_command(cmd))
end
find_runnable(file) click to toggle source
# File lib/rake/alt_system.rb, line 71
def find_runnable(file)
  if file =~ RUNNABLE_PATTERN
    file
  else
    RUNNABLE_EXTS.each { |ext|
      if File.exist?(test = "#{file}.#{ext}")
        return test
      end
    }
    nil
  end
end
repair_command(cmd) click to toggle source
# File lib/rake/alt_system.rb, line 51
def repair_command(cmd)
  "call " + (
    if cmd =~ %r\A\s*\".*?\"!
      # already quoted
      cmd
    elsif match = cmd.match(%r\A\s*(\S+)!)
      if match[1] =~ %r/!
        # avoid x/y.bat interpretation as x with option /y
        %Q"#{match[1]}"! + match.post_match
      else
        # a shell command will fail if quoted
        cmd
      end
    else
      # empty or whitespace
      cmd
    end
  )
end
system(cmd, *args) click to toggle source
# File lib/rake/alt_system.rb, line 84
def system(cmd, *args)
  repaired = (
    if args.empty?
      [repair_command(cmd)]
    elsif runnable = find_runnable(cmd)
      [File.expand_path(runnable), *args]
    else
      # non-existent file
      [cmd, *args]
    end
  )
  kernel_system(*repaired)
end


class Rake::Application - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::Application

Rake main application object. When invoking rake from the command line, a Rake::Application object is created and run.

In Files

  • lib/rake/application.rb

Parent

Object

Included Modules

  • Rake::TaskManager
  • Rake::TraceOutput

Constants

DEFAULT_RAKEFILES

Attributes

name[R]

The name of the application (typically 'rake')

original_dir[R]

The original directory where rake was invoked.

rakefile[R]

Name of the actual rakefile used.

terminal_columns[RW]

Number of columns on the terminal

top_level_tasks[R]

List of the top level task names (task names from the command line).

Public Class Methods

new() click to toggle source

Initialize a Rake::Application object.

# File lib/rake/application.rb, line 41
def initialize
  super
  @name = 'rake'
  @rakefiles = DEFAULT_RAKEFILES.dup
  @rakefile = nil
  @pending_imports = []
  @imported = []
  @loaders = {}
  @default_loader = Rake::DefaultLoader.new
  @original_dir = Dir.pwd
  @top_level_tasks = []
  add_loader('rb', DefaultLoader.new)
  add_loader('rf', DefaultLoader.new)
  add_loader('rake', DefaultLoader.new)
  @tty_output = STDOUT.tty?
  @terminal_columns = ENV['RAKE_COLUMNS'].to_i
end

Public Instance Methods

add_import(fn) click to toggle source

Add a file to the list of files to be imported.

# File lib/rake/application.rb, line 659
def add_import(fn)
  @pending_imports << fn
end
add_loader(ext, loader) click to toggle source

Add a loader to handle imported files ending in the extension ext.

# File lib/rake/application.rb, line 123
def add_loader(ext, loader)
  ext = ".#{ext}" unless ext =~ /^\./
  @loaders[ext] = loader
end
collect_tasks() click to toggle source

Collect the list of tasks on the command line. If no tasks are given, return a list containing only the default task. Environmental assignments are processed at this time as well.

# File lib/rake/application.rb, line 646
def collect_tasks
  @top_level_tasks = []
  ARGV.each do |arg|
    if arg =~ /^(\w+)=(.*)$/
      ENV[$1] = $2
    else
      @top_level_tasks << arg unless arg =~ /^-/
    end
  end
  @top_level_tasks.push("default") if @top_level_tasks.size == 0
end
const_warning(const_name) click to toggle source

Warn about deprecated use of top level constant names.

# File lib/rake/application.rb, line 678
def const_warning(const_name)
  @const_warning ||= false
  if ! @const_warning
    $stderr.puts %Q{WARNING: Deprecated reference to top-level constant '#{const_name}' } +
      %Q{found at: #{rakefile_location}} # '
    $stderr.puts %Q{    Use --classic-namespace on rake command}
    $stderr.puts %Q{    or 'require "rake/classic_namespace"' in Rakefile}
  end
  @const_warning = true
end
deprecate(old_usage, new_usage, call_site) click to toggle source

Warn about deprecated usage.

Example:

Rake.application.deprecate("import", "Rake.import", caller.first)
# File lib/rake/application.rb, line 192
def deprecate(old_usage, new_usage, call_site)
  return if options.ignore_deprecate
  $stderr.puts "WARNING: '#{old_usage}' is deprecated.  " +
    "Please use '#{new_usage}' instead.\n" +
    "    at #{call_site}"
end
display_error_message(ex) click to toggle source

Display the error message that caused the exception.

# File lib/rake/application.rb, line 175
def display_error_message(ex)
  trace "#{name} aborted!"
  trace ex.message
  if options.backtrace
    trace ex.backtrace.join("\n")
  else
    trace Backtrace.collapse(ex.backtrace).join("\n")
  end
  trace "Tasks: #{ex.chain}" if has_chain?(ex)
  trace "(See full trace by running task with --trace)" unless options.backtrace
end
display_prerequisites() click to toggle source

Display the tasks and prerequisites

# File lib/rake/application.rb, line 312
def display_prerequisites
  tasks.each do |t|
    puts "#{name} #{t.name}"
    t.prerequisites.each { |pre| puts "    #{pre}" }
  end
end
display_tasks_and_comments() click to toggle source

Display the tasks and comments.

# File lib/rake/application.rb, line 236
def display_tasks_and_comments
  displayable_tasks = tasks.select { |t|
    (options.show_all_tasks || t.comment) && t.name =~ options.show_task_pattern
  }
  case options.show_tasks
  when :tasks
    width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10
    max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil

    displayable_tasks.each do |t|
      printf "#{name} %-#{width}s  # %s\n",
        t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment
    end
  when :describe
    displayable_tasks.each do |t|
      puts "#{name} #{t.name_with_args}"
      comment = t.full_comment || ""
      comment.split("\n").each do |line|
        puts "    #{line}"
      end
      puts
    end
  when :lines
    displayable_tasks.each do |t|
      t.locations.each do |loc|
        printf "#{name} %-30s %s\n",t.name_with_args, loc
      end
    end
  else
    fail "Unknown show task mode: '#{options.show_tasks}'"
  end
end
dynamic_width() click to toggle source

Calculate the dynamic width of the

# File lib/rake/application.rb, line 281
def dynamic_width
  @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
end
dynamic_width_stty() click to toggle source
# File lib/rake/application.rb, line 285
def dynamic_width_stty
  %x{stty size 2>/dev/null}.split[1].to_i
end
dynamic_width_tput() click to toggle source
# File lib/rake/application.rb, line 289
def dynamic_width_tput
  %x{tput cols 2>/dev/null}.to_i
end
find_rakefile_location() click to toggle source
# File lib/rake/application.rb, line 569
def find_rakefile_location
  here = Dir.pwd
  while ! (fn = have_rakefile)
    Dir.chdir("..")
    if Dir.pwd == here || options.nosearch
      return nil
    end
    here = Dir.pwd
  end
  [fn, here]
ensure
  Dir.chdir(Rake.original_dir)
end
handle_options() click to toggle source

Read and handle the command line options.

# File lib/rake/application.rb, line 524
def handle_options
  options.rakelib = ['rakelib']
  options.trace_output = $stderr

  OptionParser.new do |opts|
    opts.banner = "rake [-f rakefile] {options} targets..."
    opts.separator ""
    opts.separator "Options are ..."

    opts.on_tail("-h", "--help", "-H", "Display this help message.") do
      puts opts
      exit
    end

    standard_rake_options.each { |args| opts.on(*args) }
    opts.environment('RAKEOPT')
  end.parse!

  # If class namespaces are requested, set the global options
  # according to the values in the options structure.
  if options.classic_namespace
    $show_tasks = options.show_tasks
    $show_prereqs = options.show_prereqs
    $trace = options.trace
    $dryrun = options.dryrun
    $silent = options.silent
  end
end
have_rakefile() click to toggle source

True if one of the files in RAKEFILES is in the current directory. If a match is found, it is copied into @rakefile.

# File lib/rake/application.rb, line 207
def have_rakefile
  @rakefiles.each do |fn|
    if File.exist?(fn)
      others = FileList.glob(fn, File::FNM_CASEFOLD)
      return others.size == 1 ? others.first : fn
    elsif fn == ''
      return fn
    end
  end
  return nil
end
init(app_name='rake') click to toggle source

Initialize the command line parameters and app name.

# File lib/rake/application.rb, line 78
def init(app_name='rake')
  standard_exception_handling do
    @name = app_name
    handle_options
    collect_tasks
  end
end
invoke_task(task_string) click to toggle source

private —————————————————————-

# File lib/rake/application.rb, line 140
def invoke_task(task_string)
  name, args = parse_task_string(task_string)
  t = self[name]
  t.invoke(*args)
end
load_imports() click to toggle source

Load the pending list of imported files.

# File lib/rake/application.rb, line 664
def load_imports
  while fn = @pending_imports.shift
    next if @imported.member?(fn)
    if fn_task = lookup(fn)
      fn_task.invoke
    end
    ext = File.extname(fn)
    loader = @loaders[ext] || @default_loader
    loader.load(fn)
    @imported << fn
  end
end
load_rakefile() click to toggle source

Find the rakefile and then load it and any pending imports.

# File lib/rake/application.rb, line 87
def load_rakefile
  standard_exception_handling do
    raw_load_rakefile
  end
end
options() click to toggle source

Application options from the command line

# File lib/rake/application.rb, line 129
def options
  @options ||= OpenStruct.new
end
parse_task_string(string) click to toggle source
# File lib/rake/application.rb, line 146
def parse_task_string(string)
  if string =~ /^([^\[]+)(\[(.*)\])$/
    name = $1
    args = $3.split(/\s*,\s*/)
  else
    name = string
    args = []
  end
  [name, args]
end
print_rakefile_directory(location) click to toggle source
# File lib/rake/application.rb, line 583
def print_rakefile_directory(location)
  $stderr.puts "(in #{Dir.pwd})" unless
    options.silent or original_dir == location
end
rake_require(file_name, paths=$LOAD_PATH, loaded=$") click to toggle source

Similar to the regular Ruby require command, but will check for *.rake files in addition to *.rb files.

# File lib/rake/application.rb, line 555
def rake_require(file_name, paths=$LOAD_PATH, loaded=$")
  fn = file_name + ".rake"
  return false if loaded.include?(fn)
  paths.each do |path|
    full_path = File.join(path, fn)
    if File.exist?(full_path)
      Rake.load_rakefile(full_path)
      loaded << fn
      return true
    end
  end
  fail LoadError, "Can't find #{file_name}"
end
rakefile_location(backtrace=caller) click to toggle source
# File lib/rake/application.rb, line 689
def rakefile_location(backtrace=caller)
  backtrace.map { |t| t[/([^:]+):/,1] }

  re = /^#{@rakefile}$/
  re = /#{re.source}/ if windows?

  backtrace.find { |str| str =~ re } || ''
end
run() click to toggle source

Run the Rake application. The run method performs the following three steps:

  • Initialize the command line options (init).

  • Define the tasks (load_rakefile).

  • Run the top level tasks (top_level).

If you wish to build a custom rake command, you should call init on your application. Then define any tasks. Finally, call top_level to run your top level tasks.

# File lib/rake/application.rb, line 69
def run
  standard_exception_handling do
    init
    load_rakefile
    top_level
  end
end
run_with_threads() { || ... } click to toggle source

Run the given block with the thread startup and shutdown.

# File lib/rake/application.rb, line 107
def run_with_threads
  thread_pool.gather_history if options.job_stats == :history

  yield

  thread_pool.join
  if options.job_stats
    stats = thread_pool.statistics
    puts "Maximum active threads: #{stats[:max_active_threads]}"
    puts "Total threads in play:  #{stats[:total_threads_in_play]}"
  end
  ThreadHistoryDisplay.new(thread_pool.history).show if options.job_stats == :history
end
standard_exception_handling() { || ... } click to toggle source

Provide standard exception handling for the given block.

# File lib/rake/application.rb, line 158
def standard_exception_handling
  begin
    yield
  rescue SystemExit => ex
    # Exit silently with current status
    raise
  rescue OptionParser::InvalidOption => ex
    $stderr.puts ex.message
    exit(false)
  rescue Exception => ex
    # Exit with error message
    display_error_message(ex)
    exit(false)
  end
end
standard_rake_options() click to toggle source

A list of all the standard options used in rake, suitable for passing to OptionParser.

# File lib/rake/application.rb, line 333
def standard_rake_options
  sort_options(
    [
      ['--all', '-A', "Show all tasks, even uncommented ones",
        lambda { |value|
          options.show_all_tasks = value
        }
      ],
      ['--backtrace=[OUT]', "Enable full backtrace.  OUT can be stderr (default) or stdout.",
        lambda { |value|
          options.backtrace = true
          select_trace_output(options, 'backtrace', value)
        }
      ],
      ['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace",
        lambda { |value|
          require 'rake/classic_namespace'
          options.classic_namespace = true
        }
      ],
      ['--comments', "Show commented tasks only",
        lambda { |value|
          options.show_all_tasks = !value
        }
      ],
      ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
        lambda { |value|
          select_tasks_to_show(options, :describe, value)
        }
      ],
      ['--dry-run', '-n', "Do a dry run without executing actions.",
        lambda { |value|
          Rake.verbose(true)
          Rake.nowrite(true)
          options.dryrun = true
          options.trace = true
        }
      ],
      ['--execute',  '-e CODE', "Execute some Ruby code and exit.",
        lambda { |value|
          eval(value)
          exit
        }
      ],
      ['--execute-print',  '-p CODE', "Execute some Ruby code, print the result, then exit.",
        lambda { |value|
          puts eval(value)
          exit
        }
      ],
      ['--execute-continue',  '-E CODE',
        "Execute some Ruby code, then continue with normal task processing.",
        lambda { |value| eval(value) }
      ],
      ['--jobs',  '-j [NUMBER]',
        "Specifies the maximum number of tasks to execute in parallel. (default:2)",
        lambda { |value| options.thread_pool_size = [(value || 2).to_i,2].max }
      ],
      ['--job-stats [LEVEL]',
        "Display job statistics. LEVEL=history displays a complete job list",
        lambda { |value|
          if value =~ /^history/
            options.job_stats = :history
          else
            options.job_stats = true
          end
        }
      ],
      ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.",
        lambda { |value| $:.push(value) }
      ],
      ['--multitask', '-m', "Treat all tasks as multitasks.",
        lambda { |value| options.always_multitask = true }
      ],
      ['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.",
        lambda { |value| options.nosearch = true }
      ],
      ['--prereqs', '-P', "Display the tasks and dependencies, then exit.",
        lambda { |value| options.show_prereqs = true }
      ],
      ['--quiet', '-q', "Do not log messages to standard output.",
        lambda { |value| Rake.verbose(false) }
      ],
      ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.",
        lambda { |value|
          value ||= ''
          @rakefiles.clear
          @rakefiles << value
        }
      ],
      ['--rakelibdir', '--rakelib', '-R RAKELIBDIR',
        "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')",
        lambda { |value| options.rakelib = value.split(File::PATH_SEPARATOR) }
      ],
      ['--reduce-compat', "Remove DSL in Object; remove Module#const_missing which defines ::Task etc.",
        # Load-time option.
        # Handled in bin/rake where Rake::REDUCE_COMPAT is defined (or not).
        lambda { |_| }
      ],
      ['--require', '-r MODULE', "Require MODULE before executing rakefile.",
        lambda { |value|
          begin
            require value
          rescue LoadError => ex
            begin
              rake_require value
            rescue LoadError
              raise ex
            end
          end
        }
      ],
      ['--rules', "Trace the rules resolution.",
        lambda { |value| options.trace_rules = true }
      ],
      ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.",
        lambda { |value|
          Rake.verbose(false)
          options.silent = true
        }
      ],
      ['--suppress-backtrace PATTERN', "Suppress backtrace lines matching regexp PATTERN. Ignored if --trace is on.",
        lambda { |value|
          options.suppress_backtrace_pattern = Regexp.new(value)
        }
      ],
      ['--system',  '-g',
        "Using system wide (global) rakefiles (usually '~/.rake/*.rake').",
        lambda { |value| options.load_system = true }
      ],
      ['--no-system', '--nosystem', '-G',
        "Use standard project Rakefile search paths, ignore system wide rakefiles.",
        lambda { |value| options.ignore_system = true }
      ],
      ['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.",
        lambda { |value|
          select_tasks_to_show(options, :tasks, value)
        }
      ],
      ['--trace=[OUT]', '-t', "Turn on invoke/execute tracing, enable full backtrace. OUT can be stderr (default) or stdout.",
        lambda { |value|
          options.trace = true
          options.backtrace = true
          select_trace_output(options, 'trace', value)
          Rake.verbose(true)
        }
      ],
      ['--verbose', '-v', "Log message to standard output.",
        lambda { |value| Rake.verbose(true) }
      ],
      ['--version', '-V', "Display the program version.",
        lambda { |value|
          puts "rake, version #{RAKEVERSION}"
          exit
        }
      ],
      ['--where', '-W [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
        lambda { |value|
          select_tasks_to_show(options, :lines, value)
          options.show_all_tasks = true
        }
      ],
      ['--no-deprecation-warnings', '-X', "Disable the deprecation warnings.",
        lambda { |value|
          options.ignore_deprecate = true
        }
      ],
    ])
end
system_dir() click to toggle source

The directory path containing the system wide rakefiles.

# File lib/rake/application.rb, line 620
def system_dir
  @system_dir ||=
    begin
      if ENV['RAKE_SYSTEM']
        ENV['RAKE_SYSTEM']
      else
        standard_system_dir
      end
    end
end
terminal_width() click to toggle source
# File lib/rake/application.rb, line 269
def terminal_width
  if @terminal_columns.nonzero?
    result = @terminal_columns
  else
    result = unix? ? dynamic_width : 80
  end
  (result < 10) ? 80 : result
rescue
  80
end
top_level() click to toggle source

Run the top level tasks of a Rake application.

# File lib/rake/application.rb, line 94
def top_level
  run_with_threads do
    if options.show_tasks
      display_tasks_and_comments
    elsif options.show_prereqs
      display_prerequisites
    else
      top_level_tasks.each { |task_name| invoke_task(task_name) }
    end
  end
end
trace(*strings) click to toggle source
# File lib/rake/application.rb, line 319
def trace(*strings)
  options.trace_output ||= $stderr
  trace_on(options.trace_output, *strings)
end
truncate(string, width) click to toggle source
# File lib/rake/application.rb, line 301
def truncate(string, width)
  if string.nil?
    ""
  elsif string.length <= width
    string
  else
    ( string[0, width-3] || "" ) + "..."
  end
end
truncate_output?() click to toggle source

We will truncate output if we are outputting to a TTY or if we've been given an explicit column width to honor

# File lib/rake/application.rb, line 231
def truncate_output?
  tty_output? || @terminal_columns.nonzero?
end
tty_output=( tty_output_state ) click to toggle source

Override the detected TTY output state (mostly for testing)

# File lib/rake/application.rb, line 225
def tty_output=( tty_output_state )
  @tty_output = tty_output_state
end
tty_output?() click to toggle source

True if we are outputting to TTY, false otherwise

# File lib/rake/application.rb, line 220
def tty_output?
  @tty_output
end
unix?() click to toggle source
# File lib/rake/application.rb, line 293
def unix?
  RbConfig::CONFIG['host_os'] =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/
end
windows?() click to toggle source
# File lib/rake/application.rb, line 297
def windows?
  Win32.windows?
end


module Rake::Backtrace - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake::Backtrace

In Files

  • lib/rake/backtrace.rb

Constants

SUPPRESSED_PATHS
SUPPRESS_PATTERN

Public Class Methods

collapse(backtrace) click to toggle source
# File lib/rake/backtrace.rb, line 12
def self.collapse(backtrace)
  pattern = Rake.application.options.suppress_backtrace_pattern ||
            SUPPRESS_PATTERN
  backtrace.reject { |elem| elem =~ pattern }
end


module Rake::Cloneable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake::Cloneable

########################################################################## Mixin for creating easily cloned objects.

In Files

  • lib/rake/cloneable.rb

Public Instance Methods

initialize_copy(source) click to toggle source

The hook that invoked by 'clone' and 'dup' methods.

# File lib/rake/cloneable.rb, line 7
def initialize_copy(source)
  super
  source.instance_variables.each do |var|
    src_value  = source.instance_variable_get(var)
    value = src_value.clone rescue src_value
    instance_variable_set(var, value)
  end
end


class Rake::CompositePublisher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::CompositePublisher

Manage several publishers as a single entity.

In Files

  • lib/rake/contrib/compositepublisher.rb

Parent

Object

Public Class Methods

new() click to toggle source
# File lib/rake/contrib/compositepublisher.rb, line 5
def initialize
  @publishers = []
end

Public Instance Methods

add(pub) click to toggle source

Add a publisher to the composite.

# File lib/rake/contrib/compositepublisher.rb, line 10
def add(pub)
  @publishers << pub
end
upload() click to toggle source

Upload all the individual publishers.

# File lib/rake/contrib/compositepublisher.rb, line 15
def upload
  @publishers.each { |p| p.upload }
end


module Rake::DSL - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake::DSL

DSL is a module that provides task, desc, namespace, etc. Use this when you'd like to use rake outside the top level scope.

In Files

  • lib/rake/dsl_definition.rb

Included Modules

  • Rake::FileUtilsExt


class Rake::DefaultLoader - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::DefaultLoader

Default Rakefile loader used by import.

In Files

  • lib/rake/default_loader.rb

Parent

Object

Public Instance Methods

load(fn) click to toggle source
# File lib/rake/default_loader.rb, line 5
def load(fn)
  Rake.load_rakefile(File.expand_path(fn))
end


class Rake::EarlyTime - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::EarlyTime

EarlyTime is a fake timestamp that occurs before any other time value.

In Files

  • lib/rake/early_time.rb

Parent

Object

Included Modules

  • Comparable
  • Singleton

Public Instance Methods

<=>(other) click to toggle source
# File lib/rake/early_time.rb, line 8
def <=>(other)
  -1
end
to_s() click to toggle source
# File lib/rake/early_time.rb, line 12
def to_s
  "<EARLY TIME>"
end


class Rake::FileCreationTask - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::FileCreationTask

A FileCreationTask is a file task that when used as a dependency will be needed if and only if the file has not been created. Once created, it is not re-triggered if any of its dependencies are newer, nor does trigger any rebuilds of tasks that depend on it whenever it is updated.

In Files

  • lib/rake/file_creation_task.rb

Parent

FileTask

Public Instance Methods

needed?() click to toggle source

Is this file task needed? Yes if it doesn't exist.

# File lib/rake/file_creation_task.rb, line 13
def needed?
  ! File.exist?(name)
end
timestamp() click to toggle source

Time stamp for file creation task. This time stamp is earlier than any other time stamp.

# File lib/rake/file_creation_task.rb, line 19
def timestamp
  Rake::EARLY
end


class Rake::FileList - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::FileList

######################################################################### A FileList is essentially an array with a few helper methods defined to make file manipulation a bit easier.

FileLists are lazy. When given a list of glob patterns for possible files to be included in the file list, instead of searching the file structures to find the files, a FileList holds the pattern for latter use.

This allows us to define a number of FileList to match any number of files, but only search out the actual files when then FileList itself is actually used. The key is that the first time an element of the FileList/Array is requested, the pending patterns are resolved into a real list of file names.

In Files

  • lib/rake/file_list.rb

Parent

Object

Included Modules

  • Rake::Cloneable

Constants

ARRAY_METHODS

List of array methods (that are not in Object) that need to be delegated.

DELEGATING_METHODS
MUST_DEFINE

List of additional methods that must be delegated.

MUST_NOT_DEFINE

List of methods that should not be delegated here (we define special versions of them explicitly below).

SPECIAL_RETURN

List of delegated methods that return new array values which need wrapping.

Public Class Methods

new(*patterns) { |self| ... } click to toggle source

Create a file list from the globbable patterns given. If you wish to perform multiple includes or excludes at object build time, use the “yield self” pattern.

Example:

file_list = FileList.new('lib   /*.rb', 'test/test*.rb')

pkg_files = FileList.new('lib/   *') do |fl|
  fl.exclude(/\bCVS\b/)
end

# File lib/rake/file_list.rb, line 97
def initialize(*patterns)
  @pending_add = []
  @pending = false
  @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup
  @exclude_procs = DEFAULT_IGNORE_PROCS.dup
  @items = []
  patterns.each { |pattern| include(pattern) }
  yield self if block_given?
end

Public Instance Methods

*(other) click to toggle source

Redefine * to return either a string or a new file list.

# File lib/rake/file_list.rb, line 190
def *(other)
  result = @items * other
  case result
  when Array
    FileList.new.import(result)
  else
    result
  end
end
==(array) click to toggle source

Define equality.

# File lib/rake/file_list.rb, line 168
def ==(array)
  to_ary == array
end
add(*filenames) click to toggle source
Alias for: include
clear_exclude() click to toggle source

Clear all the exclude patterns so that we exclude nothing.

# File lib/rake/file_list.rb, line 161
def clear_exclude
  @exclude_patterns = []
  @exclude_procs = []
  self
end
exclude(*patterns, &block) click to toggle source

Register a list of file name patterns that should be excluded from the list. Patterns may be regular expressions, glob patterns or regular strings. In addition, a block given to exclude will remove entries that return true when given to the block.

Note that glob patterns are expanded against the file system. If a file is explicitly added to a file list, but does not exist in the file system, then an glob pattern in the exclude list will not exclude the file.

Examples:

FileList['a.c', 'b.c'].exclude("a.c") => ['b.c']
FileList['a.c', 'b.c'].exclude(/^a/)  => ['b.c']

If “a.c” is a file, then …

FileList['a.c', 'b.c'].exclude("a.*") => ['b.c']

If “a.c” is not a file, then …

FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c']

# File lib/rake/file_list.rb, line 148
def exclude(*patterns, &block)
  patterns.each do |pat|
    @exclude_patterns << pat
  end
  if block_given?
    @exclude_procs << block
  end
  resolve_exclude if ! @pending
  self
end
include(*filenames) click to toggle source

Add file names defined by glob patterns to the file list. If an array is given, add each element of the array.

Example:

file_list.include("*.java", "*.cfg")
file_list.include %w( math.c lib.h *.o )
# File lib/rake/file_list.rb, line 114
def include(*filenames)
  # TODO: check for pending
  filenames.each do |fn|
    if fn.respond_to? :to_ary
      include(*fn.to_ary)
    else
      @pending_add << fn
    end
  end
  @pending = true
  self
end
Also aliased as: add
is_a?(klass) click to toggle source

Lie about our class.

# File lib/rake/file_list.rb, line 184
def is_a?(klass)
  klass == Array || super(klass)
end
Also aliased as: kind_of?
kind_of?(klass) click to toggle source
Alias for: is_a?
resolve() click to toggle source

Resolve all the pending adds now.

# File lib/rake/file_list.rb, line 201
def resolve
  if @pending
    @pending = false
    @pending_add.each do |fn| resolve_add(fn) end
    @pending_add = []
    resolve_exclude
  end
  self
end
resolve_add(fn) click to toggle source
# File lib/rake/file_list.rb, line 211
    def resolve_add(fn)
      case fn
      when %r{[*?\[\{]}
        add_matching(fn)
      else
        self << fn
      end
    end
    private :resolve_add

    def resolve_exclude
      reject! { |fn| exclude?(fn) }
      self
    end
    private :resolve_exclude

    # Return a new FileList with the results of running +sub+ against each
    # element of the original list.
    #
    # Example:
    #   FileList['a.c', 'b.c'].sub(/\.c$/, '.o')  => ['a.o', 'b.o']
    #
    def sub(pat, rep)
      inject(FileList.new) { |res, fn| res << fn.sub(pat,rep) }
    end

    # Return a new FileList with the results of running +gsub+ against each
    # element of the original list.
    #
    # Example:
    #   FileList['lib/test/file', 'x/y'].gsub(/\//, "\")
    #      => ['lib\test\file', 'x\y']
    #
    def gsub(pat, rep)
      inject(FileList.new) { |res, fn| res << fn.gsub(pat,rep) }
    end

    # Same as +sub+ except that the original file list is modified.
    def sub!(pat, rep)
      each_with_index { |fn, i| self[i] = fn.sub(pat,rep) }
      self
    end

    # Same as +gsub+ except that the original file list is modified.
    def gsub!(pat, rep)
      each_with_index { |fn, i| self[i] = fn.gsub(pat,rep) }
      self
    end

    # Apply the pathmap spec to each of the included file names, returning a
    # new file list with the modified paths.  (See String#pathmap for
    # details.)
    def pathmap(spec=nil)
      collect { |fn| fn.pathmap(spec) }
    end

    # Return a new FileList with <tt>String#ext</tt> method applied to
    # each member of the array.
    #
    # This method is a shortcut for:
    #
    #    array.collect { |item| item.ext(newext) }
    #
    # +ext+ is a user added method for the Array class.
    def ext(newext='')
      collect { |fn| fn.ext(newext) }
    end

    # Grep each of the files in the filelist using the given pattern. If a
    # block is given, call the block on each matching line, passing the file
    # name, line number, and the matching line of text.  If no block is given,
    # a standard emacs style file:linenumber:line message will be printed to
    # standard out.  Returns the number of matched items.
    def egrep(pattern, *options)
      matched = 0
      each do |fn|
        begin
          open(fn, "r", *options) do |inf|
            count = 0
            inf.each do |line|
              count += 1
              if pattern.match(line)
                matched += 1
                if block_given?
                  yield fn, count, line
                else
                  puts "#{fn}:#{count}:#{line}"
                end
              end
            end
          end
        rescue StandardError => ex
          $stderr.puts "Error while processing '#{fn}': #{ex}"
        end
      end
      matched
    end

    # Return a new file list that only contains file names from the current
    # file list that exist on the file system.
    def existing
      select { |fn| File.exist?(fn) }
    end

    # Modify the current file list so that it contains only file name that
    # exist on the file system.
    def existing!
      resolve
      @items = @items.select { |fn| File.exist?(fn) }
      self
    end

    # FileList version of partition.  Needed because the nested arrays should
    # be FileLists in this version.
    def partition(&block)       # :nodoc:
      resolve
      result = @items.partition(&block)
      [
        FileList.new.import(result[0]),
        FileList.new.import(result[1]),
      ]
    end

    # Convert a FileList to a string by joining all elements with a space.
    def to_s
      resolve
      self.join(' ')
    end

    # Add matching glob patterns.
    def add_matching(pattern)
      FileList.glob(pattern).each do |fn|
        self << fn unless exclude?(fn)
      end
    end
    private :add_matching

    # Should the given file name be excluded?
    def exclude?(fn)
      return true if @exclude_patterns.any? do |pat|
        case pat
        when Regexp
          fn =~ pat
        when /[*?]/
          File.fnmatch?(pat, fn, File::FNM_PATHNAME)
        else
          fn == pat
        end
      end
      @exclude_procs.any? { |p| p.call(fn) }
    end

    DEFAULT_IGNORE_PATTERNS = [
      /(^|[\/\])CVS([\/\]|$)/,
      /(^|[\/\])\.svn([\/\]|$)/,
      /\.bak$/,
      /~$/
    ]
    DEFAULT_IGNORE_PROCS = [
      proc { |fn| fn =~ /(^|[\/\])core$/ && ! File.directory?(fn) }
    ]

    def import(array)
      @items = array
      self
    end

    class << self
      # Create a new file list including the files listed. Similar to:
      #
      #   FileList.new(*args)
      def [](*args)
        new(*args)
      end

      # Get a sorted list of files matching the pattern. This method
      # should be prefered to Dir[pattern] and Dir.glob(pattern) because
      # the files returned are guaranteed to be sorted.
      def glob(pattern, *args)
        Dir.glob(pattern, *args).sort
      end
    end
  end
end

module Rake
  class << self

    # Yield each file or directory component.
    def each_dir_parent(dir)    # :nodoc:
      old_length = nil
      while dir != '.' && dir.length != old_length
        yield(dir)
        old_length = dir.length
        dir = File.dirname(dir)
      end
    end
  end
end # module Rake
to_a() click to toggle source

Return the internal array object.

# File lib/rake/file_list.rb, line 173
def to_a
  resolve
  @items
end
to_ary() click to toggle source

Return the internal array object.

# File lib/rake/file_list.rb, line 179
def to_ary
  to_a
end


class Rake::FileTask - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::FileTask

######################################################################### A FileTask is a task that includes time based dependencies. If any of a FileTask's prerequisites have a timestamp that is later than the file represented by this task, then the file must be rebuilt (using the supplied actions).

In Files

  • lib/rake/file_task.rb

Parent

Task

Public Instance Methods

needed?() click to toggle source

Is this file task needed? Yes if it doesn't exist, or if its time stamp is out of date.

# File lib/rake/file_task.rb, line 15
def needed?
  ! File.exist?(name) || out_of_date?(timestamp)
end
timestamp() click to toggle source

Time stamp for file task.

# File lib/rake/file_task.rb, line 20
def timestamp
  if File.exist?(name)
    File.mtime(name.to_s)
  else
    Rake::EARLY
  end
end


module Rake::FileUtilsExt - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake::FileUtilsExt

FileUtilsExt provides a custom version of the FileUtils methods that respond to the verbose and nowrite commands.

In Files

  • lib/rake/file_utils_ext.rb

Included Modules

  • FileUtils

Constants

DEFAULT

Attributes

nowrite_flag[RW]
verbose_flag[RW]

Public Instance Methods

nowrite(value=nil) { || ... } click to toggle source

Get/set the nowrite flag controlling output from the FileUtils utilities. If verbose is true, then the utility method is echoed to standard output.

Examples:

nowrite              # return the current value of the
                     # nowrite flag
nowrite(v)           # set the nowrite flag to _v_.
nowrite(v) { code }  # Execute code with the nowrite flag set
                     # temporarily to _v_. Return to the
                     # original value when code is done.
# File lib/rake/file_utils_ext.rb, line 80
def nowrite(value=nil)
  oldvalue = FileUtilsExt.nowrite_flag
  FileUtilsExt.nowrite_flag = value unless value.nil?
  if block_given?
    begin
      yield
    ensure
      FileUtilsExt.nowrite_flag = oldvalue
    end
  end
  oldvalue
end
rake_check_options(options, *optdecl) click to toggle source

Check that the options do not contain options not listed in optdecl. An ArgumentError exception is thrown if non-declared options are found.

# File lib/rake/file_utils_ext.rb, line 136
def rake_check_options(options, *optdecl)
  h = options.dup
  optdecl.each do |name|
    h.delete name
  end
  raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless h.empty?
end
rake_merge_option(args, defaults) click to toggle source

Merge the given options with the default values.

# File lib/rake/file_utils_ext.rb, line 119
def rake_merge_option(args, defaults)
  if Hash === args.last
    defaults.update(args.last)
    args.pop
  end
  args.push defaults
  args
end
rake_output_message(message) click to toggle source

Send the message to the default rake output (which is $stderr).

# File lib/rake/file_utils_ext.rb, line 129
def rake_output_message(message)
  $stderr.puts(message)
end
verbose(value=nil) { || ... } click to toggle source

Get/set the verbose flag controlling output from the FileUtils utilities. If verbose is true, then the utility method is echoed to standard output.

Examples:

verbose              # return the current value of the
                     # verbose flag
verbose(v)           # set the verbose flag to _v_.
verbose(v) { code }  # Execute code with the verbose flag set
                     # temporarily to _v_.  Return to the
                     # original value when code is done.
# File lib/rake/file_utils_ext.rb, line 56
def verbose(value=nil)
  oldvalue = FileUtilsExt.verbose_flag
  FileUtilsExt.verbose_flag = value unless value.nil?
  if block_given?
    begin
      yield
    ensure
      FileUtilsExt.verbose_flag = oldvalue
    end
  end
  FileUtilsExt.verbose_flag
end
when_writing(msg=nil) { || ... } click to toggle source

Use this function to prevent potentially destructive ruby code from running when the :nowrite flag is set.

Example:

when_writing("Building Project") do
  project.build
end

The following code will build the project under normal conditions. If the nowrite(true) flag is set, then the example will print:

DRYRUN: Building Project

instead of actually building the project.

# File lib/rake/file_utils_ext.rb, line 110
def when_writing(msg=nil)
  if FileUtilsExt.nowrite_flag
    $stderr.puts "DRYRUN: #{msg}" if msg
  else
    yield
  end
end


class Rake::FtpFile - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::FtpFile

Note: Not released for general use.

In Files

  • lib/rake/contrib/ftptools.rb

Parent

Object

Attributes

group[R]
name[R]
owner[R]
size[R]
time[R]

Public Class Methods

date() click to toggle source
# File lib/rake/contrib/ftptools.rb, line 17
def self.date
  @date_class ||= Date
end
new(path, entry) click to toggle source
# File lib/rake/contrib/ftptools.rb, line 25
def initialize(path, entry)
  @path = path
  @mode, _, @owner, @group, size, d1, d2, d3, @name = entry.split(' ')
  @size = size.to_i
  @time = determine_time(d1, d2, d3)
end
time() click to toggle source
# File lib/rake/contrib/ftptools.rb, line 21
def self.time
  @time_class ||= Time
end

Public Instance Methods

directory?() click to toggle source
# File lib/rake/contrib/ftptools.rb, line 36
def directory?
  @mode[0] == d
end
mode() click to toggle source
# File lib/rake/contrib/ftptools.rb, line 40
def mode
  parse_mode(@mode)
end
path() click to toggle source
# File lib/rake/contrib/ftptools.rb, line 32
def path
  File.join(@path, @name)
end
symlink?() click to toggle source
# File lib/rake/contrib/ftptools.rb, line 44
def symlink?
  @mode[0] == l
end


class Rake::FtpUploader - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::FtpUploader

Manage the uploading of files to an FTP account.

In Files

  • lib/rake/contrib/ftptools.rb

Parent

Object

Attributes

verbose[RW]

Log uploads to standard output when true.

Public Class Methods

connect(path, host, account, password) { |up| ... } click to toggle source

Create an uploader and pass it to the given block as up. When the block is complete, close the uploader.

# File lib/rake/contrib/ftptools.rb, line 93
def connect(path, host, account, password)
  up = self.new(path, host, account, password)
  begin
    yield(up)
  ensure
    up.close
  end
end
new(path, host, account, password) click to toggle source

Create an FTP uploader targeting the directory path on host using the given account and password. path will be the root path of the uploader.

# File lib/rake/contrib/ftptools.rb, line 106
def initialize(path, host, account, password)
  @created = Hash.new
  @path = path
  @ftp = Net::FTP.new(host, account, password)
  makedirs(@path)
  @ftp.chdir(@path)
end

Public Instance Methods

close() click to toggle source

Close the uploader.

# File lib/rake/contrib/ftptools.rb, line 137
def close
  @ftp.close
end
makedirs(path) click to toggle source

Create the directory path in the uploader root path.

# File lib/rake/contrib/ftptools.rb, line 115
def makedirs(path)
  route = []
  File.split(path).each do |dir|
    route << dir
    current_dir = File.join(route)
    if @created[current_dir].nil?
      @created[current_dir] = true
      $stderr.puts "Creating Directory  #{current_dir}" if @verbose
      @ftp.mkdir(current_dir) rescue nil
    end
  end
end
upload_files(wildcard) click to toggle source

Upload all files matching wildcard to the uploader's root path.

# File lib/rake/contrib/ftptools.rb, line 130
def upload_files(wildcard)
  FileList.glob(wildcard).each do |fn|
    upload(fn)
  end
end


class Rake::InvocationChain - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::InvocationChain

InvocationChain tracks the chain of task invocations to detect circular dependencies.

In Files

  • lib/rake/invocation_chain.rb

Parent

Object

Constants

EMPTY

Public Class Methods

append(value, chain) click to toggle source
# File lib/rake/invocation_chain.rb, line 27
def self.append(value, chain)
  chain.append(value)
end
new(value, tail) click to toggle source
# File lib/rake/invocation_chain.rb, line 7
def initialize(value, tail)
  @value = value
  @tail = tail
end

Public Instance Methods

append(value) click to toggle source
# File lib/rake/invocation_chain.rb, line 16
def append(value)
  if member?(value)
    fail RuntimeError, "Circular dependency detected: #{to_s} => #{value}"
  end
  self.class.new(value, self)
end
member?(obj) click to toggle source
# File lib/rake/invocation_chain.rb, line 12
def member?(obj)
  @value == obj || @tail.member?(obj)
end
to_s() click to toggle source
# File lib/rake/invocation_chain.rb, line 23
def to_s
  "#{prefix}#{@value}"
end


class Rake::InvocationChain::EmptyInvocationChain - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::InvocationChain::EmptyInvocationChain

In Files

  • lib/rake/invocation_chain.rb

Parent

Object

Public Instance Methods

append(value) click to toggle source
# File lib/rake/invocation_chain.rb, line 41
def append(value)
  InvocationChain.new(value, self)
end
member?(obj) click to toggle source
# File lib/rake/invocation_chain.rb, line 38
def member?(obj)
  false
end
to_s() click to toggle source
# File lib/rake/invocation_chain.rb, line 44
def to_s
  "TOP"
end


module Rake::InvocationExceptionMixin - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake::InvocationExceptionMixin

In Files

  • lib/rake/invocation_exception_mixin.rb

Public Instance Methods

chain() click to toggle source

Return the invocation chain (list of Rake tasks) that were in effect when this exception was detected by rake. May be null if no tasks were active.

# File lib/rake/invocation_exception_mixin.rb, line 6
def chain
  @rake_invocation_chain ||= nil
end
chain=(value) click to toggle source

Set the invocation chain in effect when this exception was detected.

# File lib/rake/invocation_exception_mixin.rb, line 12
def chain=(value)
  @rake_invocation_chain = value
end


class Rake::MakefileLoader - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::MakefileLoader

Makefile loader to be used with the import file loader.

In Files

  • lib/rake/loaders/makefile.rb

Parent

Object

Included Modules

  • Rake::DSL

Constants

SPACE_MARK

Public Instance Methods

load(fn) click to toggle source

Load the makefile dependencies in fn.

# File lib/rake/loaders/makefile.rb, line 10
def load(fn)
  lines = File.read fn
  lines.gsub!(/\ /, SPACE_MARK)
  lines.gsub!(/#[^\n]*\n/, "")
  lines.gsub!(/\\n/, ' ')
  lines.each_line do |line|
    process_line(line)
  end
end


class Rake::MultiTask - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::MultiTask

Same as a regular task, but the immediate prerequisites are done in parallel using Ruby threads.

In Files

  • lib/rake/multi_task.rb

Parent

Task


class Rake::NameSpace - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::NameSpace

The NameSpace class will lookup task names in the the scope defined by a namespace command.

In Files

  • lib/rake/name_space.rb

Parent

Object

Public Class Methods

new(task_manager, scope_list) click to toggle source

Create a namespace lookup object using the given task manager and the list of scopes.

# File lib/rake/name_space.rb, line 10
def initialize(task_manager, scope_list)
  @task_manager = task_manager
  @scope = scope_list.dup
end

Public Instance Methods

[](name) click to toggle source

Lookup a task named name in the namespace.

# File lib/rake/name_space.rb, line 16
def [](name)
  @task_manager.lookup(name, @scope)
end
tasks() click to toggle source

Return the list of tasks defined in this and nested namespaces.

# File lib/rake/name_space.rb, line 21
def tasks
  @task_manager.tasks_in_scope(@scope)
end


class Rake::PackageTask - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::PackageTask

Create a packaging task that will package the project into distributable files (e.g zip archive or tar files).

The PackageTask will create the following targets:

:package

Create all the requested package files.

:clobber_package

Delete all the package files. This target is automatically added to the main clobber target.

:repackage

Rebuild the package files from scratch, even if they are not out of date.

“#package_dir/name-version.tgz”

Create a gzipped tar package (if #need_tar is true).

“#package_dir/name-version.tar.gz”

Create a gzipped tar package (if #need_tar_gz is true).

“#package_dir/name-version.tar.bz2”

Create a bzip2'd tar package (if #need_tar_bz2 is true).

“#package_dir/name-version.zip”

Create a zip package archive (if #need_zip is true).

Example:

Rake::PackageTask.new("rake", "1.2.3") do |p|
  p.need_tar = true
  p.package_files.include("lib   /*.rb")
end

In Files

  • lib/rake/packagetask.rb

Parent

TaskLib

Attributes

name[RW]

Name of the package (from the GEM Spec).

need_tar[RW]

True if a gzipped tar file (tgz) should be produced (default is false).

need_tar_bz2[RW]

True if a bzip2'd tar file (tar.bz2) should be produced (default is false).

need_tar_gz[RW]

True if a gzipped tar file (tar.gz) should be produced (default is false).

need_zip[RW]

True if a zip file should be produced (default is false)

package_dir[RW]

Directory used to store the package files (default is 'pkg').

package_files[RW]

List of files to be included in the package.

tar_command[RW]

Tar command for gzipped or bzip2ed archives. The default is 'tar'.

version[RW]

Version of the package (e.g. '1.3.2').

zip_command[RW]

Zip command for zipped archives. The default is 'zip'.

Public Class Methods

new(name=nil, version=nil) { |self| ... } click to toggle source

Create a Package Task with the given name and version. Use :noversion as the version to build a package without a version or to provide a fully-versioned package name.

# File lib/rake/packagetask.rb, line 79
def initialize(name=nil, version=nil)
  init(name, version)
  yield self if block_given?
  define unless name.nil?
end

Public Instance Methods

define() click to toggle source

Create the tasks defined by this task library.

# File lib/rake/packagetask.rb, line 100
def define
  fail "Version required (or :noversion)" if @version.nil?
  @version = nil if :noversion == @version

  desc "Build all the packages"
  task :package

  desc "Force a rebuild of the package files"
  task :repackage => [:clobber_package, :package]

  desc "Remove package products"
  task :clobber_package do
    rm_r package_dir rescue nil
  end

  task :clobber => [:clobber_package]

  [
    [need_tar, tgz_file, "z"],
    [need_tar_gz, tar_gz_file, "z"],
    [need_tar_bz2, tar_bz2_file, "j"]
  ].each do |(need, file, flag)|
    if need
      task :package => ["#{package_dir}/#{file}"]
      file "#{package_dir}/#{file}" => [package_dir_path] + package_files do
        chdir(package_dir) do
          sh %Q{#{@tar_command} #{flag}cvf #{file} #{package_name}}
        end
      end
    end
  end

  if need_zip
    task :package => ["#{package_dir}/#{zip_file}"]
    file "#{package_dir}/#{zip_file}" => [package_dir_path] + package_files do
      chdir(package_dir) do
        sh %Q{#{@zip_command} -r #{zip_file} #{package_name}}
      end
    end
  end

  directory package_dir

  file package_dir_path => @package_files do
    mkdir_p package_dir rescue nil
    @package_files.each do |fn|
      f = File.join(package_dir_path, fn)
      fdir = File.dirname(f)
      mkdir_p(fdir) if !File.exist?(fdir)
      if File.directory?(fn)
        mkdir_p(f)
      else
        rm_f f
        safe_ln(fn, f)
      end
    end
  end
  self
end
init(name, version) click to toggle source

Initialization that bypasses the “yield self” and “define” step.

# File lib/rake/packagetask.rb, line 86
def init(name, version)
  @name = name
  @version = version
  @package_files = Rake::FileList.new
  @package_dir = 'pkg'
  @need_tar = false
  @need_tar_gz = false
  @need_tar_bz2 = false
  @need_zip = false
  @tar_command = 'tar'
  @zip_command = 'zip'
end
package_dir_path() click to toggle source
# File lib/rake/packagetask.rb, line 164
def package_dir_path
  "#{package_dir}/#{package_name}"
end
package_name() click to toggle source
# File lib/rake/packagetask.rb, line 160
def package_name
  @version ? "#{@name}-#{@version}" : @name
end
tar_bz2_file() click to toggle source
# File lib/rake/packagetask.rb, line 176
def tar_bz2_file
  "#{package_name}.tar.bz2"
end
tar_gz_file() click to toggle source
# File lib/rake/packagetask.rb, line 172
def tar_gz_file
  "#{package_name}.tar.gz"
end
tgz_file() click to toggle source
# File lib/rake/packagetask.rb, line 168
def tgz_file
  "#{package_name}.tgz"
end
zip_file() click to toggle source
# File lib/rake/packagetask.rb, line 180
def zip_file
  "#{package_name}.zip"
end


module Rake::PrivateReader - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake::PrivateReader

In Files

  • lib/rake/private_reader.rb


module Rake::PrivateReader::ClassMethods - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake::PrivateReader::ClassMethods

In Files

  • lib/rake/private_reader.rb


class Rake::PseudoStatus - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::PseudoStatus

Exit status class for times the system just gives us a nil.

In Files

  • lib/rake/pseudo_status.rb

Parent

Object

Attributes

exitstatus[R]

Public Class Methods

new(code=0) click to toggle source
# File lib/rake/pseudo_status.rb, line 7
def initialize(code=0)
  @exitstatus = code
end

Public Instance Methods

>>(n) click to toggle source
# File lib/rake/pseudo_status.rb, line 13
def >>(n)
  to_i >> n
end
exited?() click to toggle source
# File lib/rake/pseudo_status.rb, line 19
def exited?
  true
end
stopped?() click to toggle source
# File lib/rake/pseudo_status.rb, line 16
def stopped?
  false
end
to_i() click to toggle source
# File lib/rake/pseudo_status.rb, line 10
def to_i
  @exitstatus << 8
end


class Rake::RDocTask - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::RDocTask

In Files

  • lib/rake/rdoctask.rb

Parent

TaskLib


class Rake::RubyForgePublisher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::RubyForgePublisher

In Files

  • lib/rake/contrib/rubyforgepublisher.rb

Parent

SshDirPublisher

Attributes

proj_id[R]
project[R]
user[R]

Public Class Methods

new(projname, user) click to toggle source
# File lib/rake/contrib/rubyforgepublisher.rb, line 8
def initialize(projname, user)
  super(
    "#{user}@rubyforge.org",
    "/var/www/gforge-projects/#{projname}",
    "html")
end


class Rake::RuleRecursionOverflowError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::RuleRecursionOverflowError

Error indicating a recursion overflow error in task selection.

In Files

  • lib/rake/rule_recursion_overflow_error.rb

Parent

StandardError

Public Class Methods

new(*args) click to toggle source
# File lib/rake/rule_recursion_overflow_error.rb, line 6
def initialize(*args)
  super
  @targets = []
end

Public Instance Methods

add_target(target) click to toggle source
# File lib/rake/rule_recursion_overflow_error.rb, line 11
def add_target(target)
  @targets << target
end
message() click to toggle source
# File lib/rake/rule_recursion_overflow_error.rb, line 15
def message
  super + ": [" + @targets.reverse.join(' => ') + "]"
end


class Rake::SshDirPublisher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::SshDirPublisher

Publish an entire directory to an existing remote directory using SSH.

In Files

  • lib/rake/contrib/sshpublisher.rb

Parent

Object

Included Modules

  • Rake::DSL

Public Class Methods

new(host, remote_dir, local_dir) click to toggle source
# File lib/rake/contrib/sshpublisher.rb, line 11
def initialize(host, remote_dir, local_dir)
  @host = host
  @remote_dir = remote_dir
  @local_dir = local_dir
end

Public Instance Methods

upload() click to toggle source
# File lib/rake/contrib/sshpublisher.rb, line 17
def upload
  sh %Q{scp -rq #{@local_dir}/* #{@host}:#{@remote_dir}}
end


class Rake::SshFilePublisher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::SshFilePublisher

Publish a list of files to an existing remote directory.

In Files

  • lib/rake/contrib/sshpublisher.rb

Parent

Object

Included Modules

  • Rake::DSL

Public Class Methods

new(host, remote_dir, local_dir, *files) click to toggle source

Create a publisher using the give host information.

# File lib/rake/contrib/sshpublisher.rb, line 36
def initialize(host, remote_dir, local_dir, *files)
  @host = host
  @remote_dir = remote_dir
  @local_dir = local_dir
  @files = files
end

Public Instance Methods

upload() click to toggle source

Upload the local directory to the remote directory.

# File lib/rake/contrib/sshpublisher.rb, line 44
def upload
  @files.each do |fn|
    sh %Q{scp -q #{@local_dir}/#{fn} #{@host}:#{@remote_dir}}
  end
end


class Rake::SshFreshDirPublisher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::SshFreshDirPublisher

Publish an entire directory to a fresh remote directory using SSH.

In Files

  • lib/rake/contrib/sshpublisher.rb

Parent

Rake::SshDirPublisher

Public Instance Methods

upload() click to toggle source
# File lib/rake/contrib/sshpublisher.rb, line 24
def upload
  sh %Q{ssh #{@host} rm -rf #{@remote_dir}} rescue nil
  sh %Q{ssh #{@host} mkdir #{@remote_dir}}
  super
end


class Rake::Task - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::Task

######################################################################### A Task is the basic unit of work in a Rakefile. Tasks have associated actions (possibly more than one) and a list of prerequisites. When invoked, a task will first ensure that all of its prerequisites have an opportunity to run and then it will execute its own actions.

Tasks are not usually created directly using the new method, but rather use the file and task convenience methods.

In Files

  • lib/rake/task.rb

Parent

Object

Attributes

actions[R]

List of actions attached to a task.

application[RW]

Application owning this task.

comment[R]

Comment for this task. Restricted to a single line of no more than 50 characters.

full_comment[R]

Full text of the (possibly multi-line) comment.

locations[R]

File/Line locations of each of the task definitions for this task (only valid if the task was defined with the detect location option set).

prerequisites[R]

List of prerequisites for a task.

scope[R]

Array of nested namespaces names used for task lookup by this task.

sources[W]

List of sources for task.

Public Class Methods

[](task_name) click to toggle source

Return a task with the given name. If the task is not currently known, try to synthesize one from the defined rules. If no rules are found, but an existing file matches the task name, assume it is a file task with no dependencies or actions.

# File lib/rake/task.rb, line 320
def [](task_name)
  Rake.application[task_name]
end
clear() click to toggle source

Clear the task list. This cause rake to immediately forget all the tasks that have been assigned. (Normally used in the unit tests.)

# File lib/rake/task.rb, line 307
def clear
  Rake.application.clear
end
create_rule(*args, &block) click to toggle source

Define a rule for synthesizing tasks.

# File lib/rake/task.rb, line 337
def create_rule(*args, &block)
  Rake.application.create_rule(*args, &block)
end
define_task(*args, &block) click to toggle source

Define a task given args and an option block. If a rule with the given name already exists, the prerequisites and actions are added to the existing task. Returns the defined task.

# File lib/rake/task.rb, line 332
def define_task(*args, &block)
  Rake.application.define_task(self, *args, &block)
end
new(task_name, app) click to toggle source

Create a task named task_name with no actions or prerequisites. Use enhance to add actions and prerequisites.

# File lib/rake/task.rb, line 71
def initialize(task_name, app)
  @name = task_name.to_s
  @prerequisites = []
  @actions = []
  @already_invoked = false
  @full_comment = nil
  @comment = nil
  @lock = Monitor.new
  @application = app
  @scope = app.current_scope
  @arg_names = nil
  @locations = []
end
scope_name(scope, task_name) click to toggle source

Apply the scope to the task name according to the rules for this kind of task. Generic tasks will accept the scope as part of the name.

# File lib/rake/task.rb, line 344
def scope_name(scope, task_name)
  (scope + [task_name]).join(':')
end
task_defined?(task_name) click to toggle source

TRUE if the task name is already defined.

# File lib/rake/task.rb, line 325
def task_defined?(task_name)
  Rake.application.lookup(task_name) != nil
end
tasks() click to toggle source

List of all defined tasks.

# File lib/rake/task.rb, line 312
def tasks
  Rake.application.tasks
end

Public Instance Methods

add_description(description) click to toggle source

Add a description to the task. The description can consist of an option argument list (enclosed brackets) and an optional comment.

# File lib/rake/task.rb, line 246
def add_description(description)
  return if ! description
  comment = description.strip
  add_comment(comment) if comment && ! comment.empty?
end
arg_names() click to toggle source

Name of arguments for this task.

# File lib/rake/task.rb, line 112
def arg_names
  @arg_names || []
end
clear() click to toggle source

Clear the existing prerequisites and actions of a rake task.

# File lib/rake/task.rb, line 123
def clear
  clear_prerequisites
  clear_actions
  clear_comments
  self
end
clear_actions() click to toggle source

Clear the existing actions on a rake task.

# File lib/rake/task.rb, line 137
def clear_actions
  actions.clear
  self
end
clear_comments() click to toggle source

Clear the existing comments on a rake task.

# File lib/rake/task.rb, line 143
def clear_comments
  @full_comment = nil
  @comment = nil
  self
end
clear_prerequisites() click to toggle source

Clear the existing prerequisites of a rake task.

# File lib/rake/task.rb, line 131
def clear_prerequisites
  prerequisites.clear
  self
end
comment=(description) click to toggle source

Writing to the comment attribute is the same as adding a description.

# File lib/rake/task.rb, line 253
def comment=(description)
  add_description(description)
end
enhance(deps=nil, &block) click to toggle source

Enhance a task with prerequisites or actions. Returns self.

# File lib/rake/task.rb, line 86
def enhance(deps=nil, &block)
  @prerequisites |= deps if deps
  @actions << block if block_given?
  self
end
execute(args=nil) click to toggle source

Execute the actions associated with this task.

# File lib/rake/task.rb, line 213
def execute(args=nil)
  args ||= EMPTY_TASK_ARGS
  if application.options.dryrun
    application.trace "** Execute (dry run) #{name}"
    return
  end
  if application.options.trace
    application.trace "** Execute #{name}"
  end
  application.enhance_with_matching_rule(name) if @actions.empty?
  @actions.each do |act|
    case act.arity
    when 1
      act.call(self)
    else
      act.call(self, args)
    end
  end
end
inspect() click to toggle source
# File lib/rake/task.rb, line 44
def inspect
  "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>"
end
investigation() click to toggle source

Return a string describing the internal state of a task. Useful for debugging.

# File lib/rake/task.rb, line 282
def investigation
  result = "------------------------------\n"
  result << "Investigating #{name}\n"
  result << "class: #{self.class}\n"
  result <<  "task needed: #{needed?}\n"
  result <<  "timestamp: #{timestamp}\n"
  result << "pre-requisites: \n"
  prereqs = prerequisite_tasks
  prereqs.sort! {|a,b| a.timestamp <=> b.timestamp}
  prereqs.each do |p|
    result << "--#{p.name} (#{p.timestamp})\n"
  end
  latest_prereq = prerequisite_tasks.collect { |pre| pre.timestamp }.max
  result <<  "latest-prerequisite time: #{latest_prereq}\n"
  result << "................................\n\n"
  return result
end
invoke(*args) click to toggle source

Invoke the task if it is needed. Prerequisites are invoked first.

# File lib/rake/task.rb, line 150
def invoke(*args)
  task_args = TaskArguments.new(arg_names, args)
  invoke_with_call_chain(task_args, InvocationChain::EMPTY)
end
name() click to toggle source

Name of the task, including any namespace qualifiers.

# File lib/rake/task.rb, line 93
def name
  @name.to_s
end
needed?() click to toggle source

Is this task needed?

# File lib/rake/task.rb, line 234
def needed?
  true
end
prerequisite_tasks() click to toggle source

List of prerequisite tasks

# File lib/rake/task.rb, line 55
def prerequisite_tasks
  prerequisites.collect { |pre| lookup_prerequisite(pre) }
end
reenable() click to toggle source

Reenable the task, allowing its tasks to be executed if the task is invoked again.

# File lib/rake/task.rb, line 118
def reenable
  @already_invoked = false
end
set_arg_names(args) click to toggle source

Set the names of the arguments for this task. args should be an array of symbols, one for each argument name.

# File lib/rake/task.rb, line 276
def set_arg_names(args)
  @arg_names = args.map { |a| a.to_sym }
end
source() click to toggle source

First source from a rule (nil if no sources)

# File lib/rake/task.rb, line 65
def source
  @sources.first if defined?(@sources)
end
sources() click to toggle source
# File lib/rake/task.rb, line 50
def sources
  @sources ||= []
end
timestamp() click to toggle source

Timestamp for this task. Basic tasks return the current time for their time stamp. Other tasks can be more sophisticated.

# File lib/rake/task.rb, line 240
def timestamp
  prerequisite_tasks.collect { |pre| pre.timestamp }.max || Time.now
end
to_s() click to toggle source

Return task name

# File lib/rake/task.rb, line 40
def to_s
  name
end


class Rake::TaskArgumentError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::TaskArgumentError

Error indicating an ill-formed task declaration.

In Files

  • lib/rake/task_argument_error.rb

Parent

ArgumentError


class Rake::TaskArguments - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::TaskArguments

TaskArguments manage the arguments passed to a task.

In Files

  • lib/rake/task_arguments.rb

Parent

Object

Included Modules

  • Enumerable

Attributes

names[R]

Public Class Methods

new(names, values, parent=nil) click to toggle source

Create a TaskArgument object with a list of named arguments (given by :names) and a set of associated values (given by :values). :parent is the parent argument object.

# File lib/rake/task_arguments.rb, line 14
def initialize(names, values, parent=nil)
  @names = names
  @parent = parent
  @hash = {}
  names.each_with_index { |name, i|
    @hash[name.to_sym] = values[i] unless values[i].nil?
  }
end

Public Instance Methods

[](index) click to toggle source

Find an argument value by name or index.

# File lib/rake/task_arguments.rb, line 31
def [](index)
  lookup(index.to_sym)
end
each(&block) click to toggle source
# File lib/rake/task_arguments.rb, line 42
def each(&block)
  @hash.each(&block)
end
inspect() click to toggle source
# File lib/rake/task_arguments.rb, line 62
def inspect
  to_s
end
method_missing(sym, *args) click to toggle source
# File lib/rake/task_arguments.rb, line 50
def method_missing(sym, *args)
  lookup(sym.to_sym)
end
new_scope(names) click to toggle source

Create a new argument scope using the prerequisite argument names.

# File lib/rake/task_arguments.rb, line 25
def new_scope(names)
  values = names.collect { |n| self[n] }
  self.class.new(names, values, self)
end
to_hash() click to toggle source
# File lib/rake/task_arguments.rb, line 54
def to_hash
  @hash
end
to_s() click to toggle source
# File lib/rake/task_arguments.rb, line 58
def to_s
  @hash.inspect
end
values_at(*keys) click to toggle source
# File lib/rake/task_arguments.rb, line 46
def values_at(*keys)
  keys.map { |k| lookup(k) }
end
with_defaults(defaults) click to toggle source

Specify a hash of default values for task arguments. Use the defaults only if there is no specific value for the given argument.

# File lib/rake/task_arguments.rb, line 38
def with_defaults(defaults)
  @hash = defaults.merge(@hash)
end

Protected Instance Methods

lookup(name) click to toggle source
# File lib/rake/task_arguments.rb, line 68
def lookup(name)
  if @hash.has_key?(name)
    @hash[name]
  elsif @parent
    @parent.lookup(name)
  end
end


class Rake::TaskLib - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::TaskLib

Base class for Task Libraries.

In Files

  • lib/rake/tasklib.rb

Parent

Object

Included Modules

  • Rake::Cloneable
  • Rake::DSL


module Rake::TaskManager - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake::TaskManager

The TaskManager module is a mixin for managing tasks.

In Files

  • lib/rake/task_manager.rb

Attributes

last_comment[RW]

Track the last comment made in the Rakefile.

last_description[RW]

Track the last comment made in the Rakefile.

Public Class Methods

new() click to toggle source
# File lib/rake/task_manager.rb, line 9
def initialize
  super
  @tasks = Hash.new
  @rules = Array.new
  @scope = Array.new
  @last_description = nil
end

Public Instance Methods

[](task_name, scopes=nil) click to toggle source

Find a matching task for task_name.

# File lib/rake/task_manager.rb, line 44
def [](task_name, scopes=nil)
  task_name = task_name.to_s
  self.lookup(task_name, scopes) or
    enhance_with_matching_rule(task_name) or
    synthesize_file_task(task_name) or
    fail "Don't know how to build task '#{task_name}'"
end
clear() click to toggle source

Clear all tasks in this application.

# File lib/rake/task_manager.rb, line 157
def clear
  @tasks.clear
  @rules.clear
end
create_rule(*args, &block) click to toggle source
# File lib/rake/task_manager.rb, line 17
def create_rule(*args, &block)
  pattern, _, deps = resolve_args(args)
  pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
  @rules << [pattern, deps, block]
end
current_scope() click to toggle source

Return the list of scope names currently active in the task manager.

# File lib/rake/task_manager.rb, line 197
def current_scope
  @scope.dup
end
define_task(task_class, *args, &block) click to toggle source
# File lib/rake/task_manager.rb, line 23
def define_task(task_class, *args, &block)
  task_name, arg_names, deps = resolve_args(args)
  task_name = task_class.scope_name(@scope, task_name)
  deps = [deps] unless deps.respond_to?(:to_ary)
  deps = deps.collect {|d| d.to_s }
  task = intern(task_class, task_name)
  task.set_arg_names(arg_names) unless arg_names.empty?
  if Rake::TaskManager.record_task_metadata
    add_location(task)
    task.add_description(get_description(task))
  end
  task.enhance(deps, &block)
end
enhance_with_matching_rule(task_name, level=0) click to toggle source

If a rule can be found that matches the task name, enhance the task with the prerequisites and actions from the rule. Set the source attribute of the task appropriately for the rule. Return the enhanced task or nil of no rule was found.

# File lib/rake/task_manager.rb, line 127
def enhance_with_matching_rule(task_name, level=0)
  fail Rake::RuleRecursionOverflowError,
    "Rule Recursion Too Deep" if level >= 16
  @rules.each do |pattern, extensions, block|
    if pattern.match(task_name)
      task = attempt_rule(task_name, extensions, block, level)
      return task if task
    end
  end
  nil
rescue Rake::RuleRecursionOverflowError => ex
  ex.add_target(task_name)
  fail ex
end
in_namespace(name) { |ns| ... } click to toggle source

Evaluate the block in a nested namespace named name. Create an anonymous namespace if name is nil.

# File lib/rake/task_manager.rb, line 203
def in_namespace(name)
  name ||= generate_name
  @scope.push(name)
  ns = NameSpace.new(self, @scope)
  yield(ns)
  ns
ensure
  @scope.pop
end
intern(task_class, task_name) click to toggle source

Lookup a task. Return an existing task if found, otherwise create a task of the current type.

# File lib/rake/task_manager.rb, line 39
def intern(task_class, task_name)
  @tasks[task_name.to_s] ||= task_class.new(task_name, self)
end
lookup(task_name, initial_scope=nil) click to toggle source

Lookup a task, using scope and the scope hints in the task name. This method performs straight lookups without trying to synthesize file tasks or rules. Special scope names (e.g. '^') are recognized. If no scope argument is supplied, use the current scope. Return nil if the task cannot be found.

# File lib/rake/task_manager.rb, line 167
def lookup(task_name, initial_scope=nil)
  initial_scope ||= @scope
  task_name = task_name.to_s
  if task_name =~ /^rake:/
    scopes = []
    task_name = task_name.sub(/^rake:/, '')
  elsif task_name =~ /^(\^+)/
    scopes = initial_scope[0, initial_scope.size - $1.size]
    task_name = task_name.sub(/^(\^+)/, '')
  else
    scopes = initial_scope
  end
  lookup_in_scope(task_name, scopes)
end
resolve_args(args) click to toggle source

Resolve the arguments for a task/rule. Returns a triplet of [task_name, arg_name_list, prerequisites].

# File lib/rake/task_manager.rb, line 59
def resolve_args(args)
  if args.last.is_a?(Hash)
    deps = args.pop
    resolve_args_with_dependencies(args, deps)
  else
    resolve_args_without_dependencies(args)
  end
end
synthesize_file_task(task_name) click to toggle source
# File lib/rake/task_manager.rb, line 52
def synthesize_file_task(task_name)
  return nil unless File.exist?(task_name)
  define_task(Rake::FileTask, task_name)
end
tasks() click to toggle source

List of all defined tasks in this application.

# File lib/rake/task_manager.rb, line 143
def tasks
  @tasks.values.sort_by { |t| t.name }
end
tasks_in_scope(scope) click to toggle source

List of all the tasks defined in the given scope (and its sub-scopes).

# File lib/rake/task_manager.rb, line 149
def tasks_in_scope(scope)
  prefix = scope.join(":")
  tasks.select { |t|
    /^#{prefix}:/ =~ t.name
  }
end


class Rake::TestTask - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::TestTask

Create a task that runs a set of tests.

Example:

Rake::TestTask.new do |t|
  t.libs << "test"
  t.test_files = FileList['test/test*.rb']
  t.verbose = true
end

If rake is invoked with a “TEST=filename” command line option, then the list of test files will be overridden to include only the filename specified on the command line. This provides an easy way to run just one test.

If rake is invoked with a “TESTOPTS=options” command line option, then the given options are passed to the test process after a '–'. This allows Test::Unit options to be passed to the test suite.

Examples:

rake test                           # run tests normally
rake test TEST=just_one_file.rb     # run just one test file.
rake test TESTOPTS="-v"             # run in verbose mode
rake test TESTOPTS="--runner=fox"   # use the fox test runner

In Files

  • lib/rake/testtask.rb

Parent

Rake::TaskLib

Attributes

libs[RW]

List of directories to added to $LOAD_PATH before running the tests. (default is 'lib')

loader[RW]

Style of test loader to use. Options are:

  • :rake – Rake provided test loading script (default).

  • :testrb – Ruby provided test loading script.

  • :direct – Load tests using command line loader.

name[RW]

Name of test task. (default is :test)

options[RW]

Test options passed to the test suite. An explicit TESTOPTS=opts on the command line will override this. (default is NONE)

pattern[RW]

Glob pattern to match test files. (default is 'test/test*.rb')

ruby_opts[RW]

Array of commandline options to pass to ruby when running test loader.

verbose[RW]

True if verbose test output desired. (default is false)

warning[RW]

Request that the tests be run with the warning flag set. E.g. warning=true implies “ruby -w” used to run the tests.

Public Class Methods

new(name=:test) { |self| ... } click to toggle source

Create a testing task.

# File lib/rake/testtask.rb, line 79
def initialize(name=:test)
  @name = name
  @libs = ["lib"]
  @pattern = nil
  @options = nil
  @test_files = nil
  @verbose = false
  @warning = false
  @loader = :rake
  @ruby_opts = []
  yield self if block_given?
  @pattern = 'test/test*.rb' if @pattern.nil? && @test_files.nil?
  define
end

Public Instance Methods

define() click to toggle source

Create the tasks defined by this task lib.

# File lib/rake/testtask.rb, line 95
def define
  desc "Run tests" + (@name==:test ? "" : " for #{@name}")
  task @name do
    FileUtilsExt.verbose(@verbose) do
      args = "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}"
      ruby args do |ok, status|
        if !ok && status.respond_to?(:signaled?) && status.signaled?
          raise SignalException.new(status.termsig)
        elsif !ok
          fail "Command failed with status (#{status.exitstatus}): [ruby #{args}]"
        end
      end
    end
  end
  self
end
file_list_string() click to toggle source
# File lib/rake/testtask.rb, line 132
def file_list_string
  file_list.collect { |fn| "\"#{fn}\"" }.join(' ')
end
lib_path() click to toggle source
# File lib/rake/testtask.rb, line 128
def lib_path
  @libs.join(File::PATH_SEPARATOR)
end
ruby_opts_string() click to toggle source
# File lib/rake/testtask.rb, line 121
def ruby_opts_string
  opts = @ruby_opts.dup
  opts.unshift( "-I\"#{lib_path}\"" ) unless @libs.empty?
  opts.unshift( "-w" ) if @warning
  opts.join(" ")
end
ruby_version() click to toggle source
# File lib/rake/testtask.rb, line 156
def ruby_version
  RUBY_VERSION
end
run_code() click to toggle source
# File lib/rake/testtask.rb, line 160
def run_code
  case @loader
  when :direct
    "-e \"ARGV.each{|f| require f}\""
  when :testrb
    "-S testrb #{fix}"
  when :rake
    "-I\"#{rake_lib_dir}\" \"#{rake_loader}\""
  end
end
test_files=(list) click to toggle source

Explicitly define the list of test files to be included in a test. list is expected to be an array of file names (a FileList is acceptable). If both pattern and test_files are used, then the list of test files is the union of the two.

# File lib/rake/testtask.rb, line 74
def test_files=(list)
  @test_files = list
end


module Rake::TraceOutput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake::TraceOutput

In Files

  • lib/rake/trace_output.rb

Public Instance Methods

trace_on(out, *strings) click to toggle source

Write trace output to output stream out.

The write is done as a single IO call (to print) to lessen the chance that the trace output is interrupted by other tasks also producing output.

# File lib/rake/trace_output.rb, line 9
def trace_on(out, *strings)
  sep = $\ || "\n"
  if strings.empty?
    output = sep
  else
    output = strings.map { |s| s.end_with?(sep) ? s : s + sep }.join
  end
  out.print(output)
end


module Rake::Win32 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rake::Win32

Win 32 interface methods for Rake. Windows specific functionality will be placed here to collect that knowledge in one spot.

In Files

  • lib/rake/win32.rb

Public Class Methods

normalize(path) click to toggle source

Normalize a win32 path so that the slashes are all forward slashes.

# File lib/rake/win32.rb, line 49
def normalize(path)
  path.gsub(/\/, '/')
end
rake_system(*cmd) click to toggle source

Run a command line on windows.

# File lib/rake/win32.rb, line 21
def rake_system(*cmd)
  AltSystem.system(*cmd)
end
windows?() click to toggle source

True if running on a windows system.

# File lib/rake/win32.rb, line 16
def windows?
  AltSystem::WINDOWS
end


class Rake::Win32::Win32HomeError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rake::Win32::Win32HomeError

Error indicating a problem in locating the home directory on a Win32 system.

In Files

  • lib/rake/win32.rb

Parent

RuntimeError


class Range - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Range

Range serialization/deserialization

In Files

  • lib/pp.rb
  • ext/json/lib/json/add/range.rb

Parent

Object

Public Class Methods

json_create(object) click to toggle source

Deserializes JSON string by constructing new Range object with arguments a serialized by to_json.

# File ext/json/lib/json/add/range.rb, line 10
def self.json_create(object)
  new(*object['a'])
end

Public Instance Methods

as_json(*) click to toggle source

Returns a hash, that will be turned into a JSON object and represent this object.

# File ext/json/lib/json/add/range.rb, line 16
def as_json(*)
  {
    JSON.create_id  => self.class.name,
    'a'             => [ first, last, exclude_end? ]
  }
end
pretty_print(q) click to toggle source
# File lib/pp.rb, line 382
def pretty_print(q)
  q.pp self.begin
  q.breakable ''
  q.text(self.exclude_end? ? '...' : '..')
  q.breakable ''
  q.pp self.end
end
to_json(*args) click to toggle source

Stores class name (Range) with JSON array of arguments a which include first (integer), last (integer), and exclude_end? (boolean) as JSON string.

# File ext/json/lib/json/add/range.rb, line 26
def to_json(*args)
  as_json.to_json(*args)
end


class Rational - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rational

When mathn is required Rational is changed to simplify the use of Rational operations.

Normal behaviour:

Rational.new!(1,3) ** 2 # => Rational(1, 9)
(1 / 3) ** 2            # => 0

require 'mathn' behaviour:

(1 / 3) ** 2            # => 1/9

In Files

  • lib/mathn.rb
  • ext/bigdecimal/lib/bigdecimal/util.rb
  • ext/json/lib/json/add/rational.rb

Parent

Numeric

Public Class Methods

json_create(object) click to toggle source
# File ext/json/lib/json/add/rational.rb, line 7
def self.json_create(object)
  Rational(object['n'], object['d'])
end

Public Instance Methods

**(other) click to toggle source

Exponentiate by other

(1/3) ** 2 # => 1/9

# File lib/mathn.rb, line 138
def ** (other)
  if other.kind_of?(Rational)
    other2 = other
    if self < 0
      return Complex(self, 0.0) ** other
    elsif other == 0
      return Rational(1,1)
    elsif self == 0
      return Rational(0,1)
    elsif self == 1
      return Rational(1,1)
    end

    npd = numerator.prime_division
    dpd = denominator.prime_division
    if other < 0
      other = -other
      npd, dpd = dpd, npd
    end

    for elm in npd
      elm[1] = elm[1] * other
      if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
        return Float(self) ** other2
      end
      elm[1] = elm[1].to_i
    end

    for elm in dpd
      elm[1] = elm[1] * other
      if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
        return Float(self) ** other2
      end
      elm[1] = elm[1].to_i
    end

    num = Integer.from_prime_division(npd)
    den = Integer.from_prime_division(dpd)

    Rational(num,den)

  elsif other.kind_of?(Integer)
    if other > 0
      num = numerator ** other
      den = denominator ** other
    elsif other < 0
      num = denominator ** -other
      den = numerator ** -other
    elsif other == 0
      num = 1
      den = 1
    end
    Rational(num, den)
  elsif other.kind_of?(Float)
    Float(self) ** other
  else
    x , y = other.coerce(self)
    x ** y
  end
end
as_json(*) click to toggle source
# File ext/json/lib/json/add/rational.rb, line 11
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'n'            => numerator,
    'd'            => denominator,
  }
end
to_d(precision) → bigdecimal click to toggle source

Converts a Rational to a BigDecimal.

The required precision parameter is used to determine the amount of significant digits for the result. See BigDecimal#div for more information, as it is used along with the denominator and the precision for parameters.

r = (22/7.0).to_r
# => (7077085128725065/2251799813685248)
r.to_d(3)
# => #<BigDecimal:1a44d08,'0.314E1',18(36)>

# File ext/bigdecimal/lib/bigdecimal/util.rb, line 99
def to_d(precision)
  if precision <= 0
    raise ArgumentError, "negative precision"
  end
  num = self.numerator
  BigDecimal(num).div(self.denominator, precision)
end
to_json(*) click to toggle source
# File ext/json/lib/json/add/rational.rb, line 19
def to_json(*)
  as_json.to_json
end


module Readline - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Readline

The Readline module provides interface for GNU Readline. This module defines a number of methods to facilitate completion and accesses input history from the Ruby interpreter. This module supported Edit Line(libedit) too. libedit is compatible with GNU Readline.

GNU Readline

www.gnu.org/directory/readline.html

libedit

www.thrysoee.dk/editline/

Reads one inputted line with line edit by ::readline method. At this time, the facilitatation completion and the key bind like Emacs can be operated like GNU Readline.

require "readline"
while buf = Readline.readline("> ", true)
  p buf
end

The content that the user input can be recorded to the history. The history can be accessed by Readline::HISTORY constant.

require "readline"
while buf = Readline.readline("> ", true)
  p Readline::HISTORY.to_a
  print("-> ", buf, "\n")
end

Most of methods raise SecurityError exception if $SAFE is 4.

Documented by TAKAO Kouji <kouji at takao7 dot net>.

In Files

  • ext/readline/readline.c

Constants

FILENAME_COMPLETION_PROC

The Object with the call method that is a completion for filename. This is sets by ::completion_proc= method.

HISTORY

The history buffer. It extends Enumerable module, so it behaves just like an array. For example, gets the fifth content that the user input by HISTORY.

USERNAME_COMPLETION_PROC

The Object with the call method that is a completion for usernames. This is sets by ::completion_proc= method.

VERSION

Version string of GNU Readline or libedit.

Public Class Methods

basic_quote_characters → string click to toggle source

Gets a list of quote characters which can cause a word break.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_get_basic_quote_characters(VALUE self, VALUE str)
{
    rb_secure(4);
    if (rl_basic_quote_characters == NULL)
        return Qnil;
    return rb_locale_str_new_cstr(rl_basic_quote_characters);
}
basic_quote_characters = string click to toggle source

Sets a list of quote characters which can cause a word break.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_set_basic_quote_characters(VALUE self, VALUE str)
{
    static char *basic_quote_characters = NULL;

    rb_secure(4);
    OutputStringValue(str);
    if (basic_quote_characters == NULL) {
        basic_quote_characters =
            ALLOC_N(char, RSTRING_LEN(str) + 1);
    }
    else {
        REALLOC_N(basic_quote_characters, char, RSTRING_LEN(str) + 1);
    }
    strncpy(basic_quote_characters,
            RSTRING_PTR(str), RSTRING_LEN(str));
    basic_quote_characters[RSTRING_LEN(str)] = '\0';
    rl_basic_quote_characters = basic_quote_characters;

    return self;
}
basic_word_break_characters → string click to toggle source

Gets the basic list of characters that signal a break between words for the completer routine.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_get_basic_word_break_characters(VALUE self, VALUE str)
{
    rb_secure(4);
    if (rl_basic_word_break_characters == NULL)
        return Qnil;
    return rb_locale_str_new_cstr(rl_basic_word_break_characters);
}
basic_word_break_characters = string click to toggle source

Sets the basic list of characters that signal a break between words for the completer routine. The default is the characters which break words for completion in Bash: “ tn"\'`@$><=;|&{(”.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_set_basic_word_break_characters(VALUE self, VALUE str)
{
    static char *basic_word_break_characters = NULL;

    rb_secure(4);
    OutputStringValue(str);
    if (basic_word_break_characters == NULL) {
        basic_word_break_characters =
            ALLOC_N(char, RSTRING_LEN(str) + 1);
    }
    else {
        REALLOC_N(basic_word_break_characters, char, RSTRING_LEN(str) + 1);
    }
    strncpy(basic_word_break_characters,
            RSTRING_PTR(str), RSTRING_LEN(str));
    basic_word_break_characters[RSTRING_LEN(str)] = '\0';
    rl_basic_word_break_characters = basic_word_break_characters;
    return self;
}
completer_quote_characters → string click to toggle source

Gets a list of characters which can be used to quote a substring of the line.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_get_completer_quote_characters(VALUE self, VALUE str)
{
    rb_secure(4);
    if (rl_completer_quote_characters == NULL)
        return Qnil;
    return rb_locale_str_new_cstr(rl_completer_quote_characters);
}
completer_quote_characters = string click to toggle source

Sets a list of characters which can be used to quote a substring of the line. Completion occurs on the entire substring, and within the substring ::completer_word_break_characters are treated as any other character, unless they also appear within this list.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_set_completer_quote_characters(VALUE self, VALUE str)
{
    static char *completer_quote_characters = NULL;

    rb_secure(4);
    OutputStringValue(str);
    if (completer_quote_characters == NULL) {
        completer_quote_characters =
            ALLOC_N(char, RSTRING_LEN(str) + 1);
    }
    else {
        REALLOC_N(completer_quote_characters, char, RSTRING_LEN(str) + 1);
    }
    strncpy(completer_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
    completer_quote_characters[RSTRING_LEN(str)] = '\0';
    rl_completer_quote_characters = completer_quote_characters;

    return self;
}
completer_word_break_characters → string click to toggle source

Gets the basic list of characters that signal a break between words for rl_complete_internal().

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_get_completer_word_break_characters(VALUE self, VALUE str)
{
    rb_secure(4);
    if (rl_completer_word_break_characters == NULL)
        return Qnil;
    return rb_locale_str_new_cstr(rl_completer_word_break_characters);
}
completer_word_break_characters = string click to toggle source

Sets the basic list of characters that signal a break between words for rl_complete_internal(). The default is the value of ::basic_word_break_characters.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_set_completer_word_break_characters(VALUE self, VALUE str)
{
    static char *completer_word_break_characters = NULL;

    rb_secure(4);
    OutputStringValue(str);
    if (completer_word_break_characters == NULL) {
        completer_word_break_characters =
            ALLOC_N(char, RSTRING_LEN(str) + 1);
    }
    else {
        REALLOC_N(completer_word_break_characters, char, RSTRING_LEN(str) + 1);
    }
    strncpy(completer_word_break_characters,
            RSTRING_PTR(str), RSTRING_LEN(str));
    completer_word_break_characters[RSTRING_LEN(str)] = '\0';
    rl_completer_word_break_characters = completer_word_break_characters;
    return self;
}
completion_append_character → char click to toggle source

Returns a string containing a character to be appended on completion. The default is a space (“ ”).

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_get_completion_append_character(VALUE self)
{
    char buf[1];

    rb_secure(4);
    if (rl_completion_append_character == '\0')
        return Qnil;

    buf[0] = (char) rl_completion_append_character;
    return rb_locale_str_new(buf, 1);
}
completion_append_character = char click to toggle source

Specifies a character to be appended on completion. Nothing will be appended if an empty string (“”) or nil is specified.

For example:

require "readline"

Readline.readline("> ", true)
Readline.completion_append_character = " "

Result:

>
Input "/var/li".

> /var/li
Press TAB key.

> /var/lib
Completes "b" and appends " ". So, you can continuously input "/usr".

> /var/lib /usr

NOTE: Only one character can be specified. When “string” is specified, sets only “s” that is the first.

require "readline"

Readline.completion_append_character = "string"
p Readline.completion_append_character # => "s"

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_set_completion_append_character(VALUE self, VALUE str)
{
    rb_secure(4);
    if (NIL_P(str)) {
        rl_completion_append_character = '\0';
    }
    else {
        OutputStringValue(str);
        if (RSTRING_LEN(str) == 0) {
            rl_completion_append_character = '\0';
        } else {
            rl_completion_append_character = RSTRING_PTR(str)[0];
        }
    }
    return self;
}
completion_case_fold → bool click to toggle source

Returns true if completion ignores case. If no, returns false.

NOTE: Returns the same object that is specified by ::completion_case_fold= method.

require "readline"

Readline.completion_case_fold = "This is a String."
p Readline.completion_case_fold # => "This is a String."

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_get_completion_case_fold(VALUE self)
{
    rb_secure(4);
    return rb_attr_get(mReadline, completion_case_fold);
}
completion_case_fold = bool click to toggle source

Sets whether or not to ignore case on completion.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_set_completion_case_fold(VALUE self, VALUE val)
{
    rb_secure(4);
    return rb_ivar_set(mReadline, completion_case_fold, val);
}
completion_proc → proc click to toggle source

Returns the completion Proc object.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_get_completion_proc(VALUE self)
{
    rb_secure(4);
    return rb_attr_get(mReadline, completion_proc);
}
completion_proc = proc click to toggle source

Specifies a Proc object proc to determine completion behavior. It should take input string and return an array of completion candidates.

The default completion is used if proc is nil.

The String that is passed to the Proc depends on the ::completer_word_break_characters property. By default the word under the cursor is passed to the Proc. For example, if the input is “foo bar” then only “bar” would be passed to the completion Proc.

Upon successful completion the ::completion_append_character will be appended to the input so the user can start working on their next argument.

Examples

Completion for a Static List

require 'readline'

LIST = [
  'search', 'download', 'open',
  'help', 'history', 'quit',
  'url', 'next', 'clear',
  'prev', 'past'
].sort

comp = proc { |s| LIST.grep(/^#{Regexp.escape(s)}/) }

Readline.completion_append_character = " "
Readline.completion_proc = comp

while line = Readline.readline('> ', true)
  p line
end

Completion For Directory Contents

require 'readline'

Readline.completion_append_character = " "
Readline.completion_proc = Proc.new do |str|
  Dir[str+'*'].grep(/^#{Regexp.escape(str)}/)
end

while line = Readline.readline('> ', true)
  p line
end

Autocomplete strategies

When working with auto-complete there are some strategies that work well. To get some ideas you can take a look at the completion.rb file for irb.

The common strategy is to take a list of possible completions and filter it down to those completions that start with the user input. In the above examples Enumerator.grep is used. The input is escaped to prevent Regexp special characters from interfering with the matching.

It may also be helpful to use the Abbrev library to generate completions.

Raises ArgumentError if proc does not respond to the call method.

Raises SecurityError if $SAFE is 4.

static VALUE
readline_s_set_completion_proc(VALUE self, VALUE proc)
{
    rb_secure(4);
    if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
        rb_raise(rb_eArgError, "argument must respond to `call'");
    return rb_ivar_set(mReadline, completion_proc, proc);
}
emacs_editing_mode → nil click to toggle source

Specifies Emacs editing mode. The default is this mode. See the manual of GNU Readline for details of Emacs editing mode.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_emacs_editing_mode(VALUE self)
{
    rb_secure(4);
    rl_emacs_editing_mode(1,0);
    return Qnil;
}
emacs_editing_mode? → bool click to toggle source

Returns true if emacs mode is active. Returns false if not.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_emacs_editing_mode_p(VALUE self)
{
    rb_secure(4);
    return rl_editing_mode == 1 ? Qtrue : Qfalse;
}
filename_quote_characters → string click to toggle source

Gets a list of characters that cause a filename to be quoted by the completer when they appear in a completed filename.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_get_filename_quote_characters(VALUE self, VALUE str)
{
    rb_secure(4);
    if (rl_filename_quote_characters == NULL)
        return Qnil;
    return rb_locale_str_new_cstr(rl_filename_quote_characters);
}
filename_quote_characters = string click to toggle source

Sets a list of characters that cause a filename to be quoted by the completer when they appear in a completed filename. The default is nil.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_set_filename_quote_characters(VALUE self, VALUE str)
{
    static char *filename_quote_characters = NULL;

    rb_secure(4);
    OutputStringValue(str);
    if (filename_quote_characters == NULL) {
        filename_quote_characters =
            ALLOC_N(char, RSTRING_LEN(str) + 1);
    }
    else {
        REALLOC_N(filename_quote_characters, char, RSTRING_LEN(str) + 1);
    }
    strncpy(filename_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
    filename_quote_characters[RSTRING_LEN(str)] = '\0';
    rl_filename_quote_characters = filename_quote_characters;

    return self;
}
get_screen_size → [rows, columns] click to toggle source

Returns the terminal's rows and columns.

See GNU Readline's rl_get_screen_size function.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_get_screen_size(VALUE self)
{
    int rows, columns;
    VALUE res;

    rb_secure(4);
    rl_get_screen_size(&rows, &columns);
    res = rb_ary_new();
    rb_ary_push(res, INT2NUM(rows));
    rb_ary_push(res, INT2NUM(columns));
    return res;
}
input = input click to toggle source

Specifies a File object input that is input stream for ::readline method.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_set_input(VALUE self, VALUE input)
{
    rb_io_t *ifp;

    rb_secure(4);
    Check_Type(input, T_FILE);
    GetOpenFile(input, ifp);
    rl_instream = rb_io_stdio_file(ifp);
#ifdef HAVE_RL_GETC_FUNCTION
    readline_instream = input;
#endif
    return input;
}
insert_text(string) → self click to toggle source

Insert text into the line at the current cursor position.

See GNU Readline's rl_insert_text function.

Raises SecurityError if $SAFE is 4.

static VALUE
readline_s_insert_text(VALUE self, VALUE str)
{
    rb_secure(4);
    OutputStringValue(str);
    rl_insert_text(RSTRING_PTR(str));
    return self;
}
line_buffer → string click to toggle source

Returns the full line that is being edited. This is useful from within the complete_proc for determining the context of the completion request.

The length of Readline.line_buffer and GNU Readline's rl_end are same.

static VALUE
readline_s_get_line_buffer(VALUE self)
{
    rb_secure(4);
    if (rl_line_buffer == NULL)
        return Qnil;
    return rb_locale_str_new_cstr(rl_line_buffer);
}
output = output click to toggle source

Specifies a File object output that is output stream for ::readline method.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_set_output(VALUE self, VALUE output)
{
    rb_io_t *ofp;

    rb_secure(4);
    Check_Type(output, T_FILE);
    GetOpenFile(output, ofp);
    rl_outstream = rb_io_stdio_file(ofp);
    return output;
}
point → int click to toggle source

Returns the index of the current cursor position in Readline.line_buffer.

The index in Readline.line_buffer which matches the start of input-string passed to ::completion_proc is computed by subtracting the length of input-string from Readline.point.

start = (the length of input-string) - Readline.point
static VALUE
readline_s_get_point(VALUE self)
{
    rb_secure(4);
    return INT2NUM(rl_point);
}
pre_input_hook → proc click to toggle source

Returns a Proc object proc to call after the first prompt has been printed and just before readline starts reading input characters. The default is nil.

Raises SecurityError if $SAFE is 4.

static VALUE
readline_s_get_pre_input_hook(VALUE self)
{
    rb_secure(4);
    return rb_attr_get(mReadline, id_pre_input_hook);
}
pre_input_hook = proc click to toggle source

Specifies a Proc object proc to call after the first prompt has been printed and just before readline starts reading input characters.

See GNU Readline's rl_pre_input_hook variable.

Raises ArgumentError if proc does not respond to the call method.

Raises SecurityError if $SAFE is 4.

static VALUE
readline_s_set_pre_input_hook(VALUE self, VALUE proc)
{
    rb_secure(4);
    if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
        rb_raise(rb_eArgError, "argument must respond to `call'");
    return rb_ivar_set(mReadline, id_pre_input_hook, proc);
}
readline(prompt = "", add_hist = false) → string or nil click to toggle source

Shows the prompt and reads the inputted line with line editing. The inputted line is added to the history if add_hist is true.

Returns nil when the inputted line is empty and user inputs EOF (Presses ^D on UNIX).

Raises IOError exception if below conditions are satisfied.

  1. stdin is not tty.

  2. stdin was closed. (errno is EBADF after called isatty(2).)

This method supports thread. Switchs the thread context when waits inputting line.

Supports line edit when inputs line. Provides VI and Emacs editing mode. Default is Emacs editing mode.

NOTE: Terminates ruby interpreter and does not return the terminal status after user pressed '^C' when wait inputting line. Give 3 examples that avoid it.

  • Catches the Interrupt exception by pressed ^C after returns terminal status:

    require "readline"

stty_save = %xstty -g`.chomp
begin
  while buf = Readline.readline
      p buf
      end
    rescue Interrupt
      system("stty", stty_save)
      exit
    end
  end
end

  • Catches the INT signal by pressed ^C after returns terminal status:

    require "readline"

stty_save = %xstty -g`.chomp
trap("INT") { system "stty", stty_save; exit }

while buf = Readline.readline
  p buf
end

  • Ignores pressing ^C:

    require "readline"

trap("INT", "SIG_IGN")

while buf = Readline.readline
  p buf
end

Can make as follows with Readline::HISTORY constant. It does not record to the history if the inputted line is empty or the same it as last one.

require "readline"

while buf = Readline.readline("> ", true)
  # p Readline::HISTORY.to_a
  Readline::HISTORY.pop if /^\s*$/ =~ buf

  begin
    if Readline::HISTORY[Readline::HISTORY.length-2] == buf
      Readline::HISTORY.pop
    end
  rescue IndexError
  end

  # p Readline::HISTORY.to_a
  print "-> ", buf, "\n"
end

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_readline(int argc, VALUE *argv, VALUE self)
{
    VALUE tmp, add_hist, result;
    char *prompt = NULL;
    char *buff;
    int status;

    rb_secure(4);
    if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) {
        OutputStringValue(tmp);
#if USE_INSERT_IGNORE_ESCAPE
        tmp = insert_ignore_escape(self, tmp);
        rb_str_locktmp(tmp);
#endif
        prompt = RSTRING_PTR(tmp);
    }

    if (!isatty(fileno(rl_instream)) && errno == EBADF) rb_raise(rb_eIOError, "closed stdin");
    if (rl_outstream) {
        struct stat stbuf;
        int fd = fileno(rl_outstream);
        if (fd < 0 || fstat(fd, &stbuf) != 0) {
            rb_raise(rb_eIOError, "closed stdout");
        }
    }

#ifdef _WIN32
    rl_prep_terminal(1);
#endif
    buff = (char*)rb_protect(readline_get, (VALUE)prompt, &status);
#if USE_INSERT_IGNORE_ESCAPE
    if (prompt) {
        rb_str_unlocktmp(tmp);
    }
#endif
    if (status) {
#if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
        /* restore terminal mode and signal handler*/
#if defined HAVE_RL_FREE_LINE_STATE
        rl_free_line_state();
#endif
        rl_cleanup_after_signal();
#elif defined HAVE_RL_DEPREP_TERM_FUNCTION
        /* restore terminal mode */
        if (rl_deprep_term_function != NULL) /* NULL in libedit. [ruby-dev:29116] */
            (*rl_deprep_term_function)();
        else
#else
        rl_deprep_terminal();
#endif
        rb_jump_tag(status);
    }

    if (RTEST(add_hist) && buff) {
        add_history(buff);
    }
    if (buff) {
        result = rb_locale_str_new_cstr(buff);
    }
    else
        result = Qnil;
    if (buff) free(buff);
    return result;
}
redisplay → self click to toggle source

Change what's displayed on the screen to reflect the current contents.

See GNU Readline's rl_redisplay function.

Raises SecurityError if $SAFE is 4.

static VALUE
readline_s_redisplay(VALUE self)
{
    rb_secure(4);
    rl_redisplay();
    return self;
}
refresh_line → nil click to toggle source

Clear the current input line.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_refresh_line(VALUE self)
{
    rb_secure(4);
    rl_refresh_line(0, 0);
    return Qnil;
}
set_screen_size(rows, columns) → self click to toggle source

Set terminal size to rows and columns.

See GNU Readline's rl_set_screen_size function.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_set_screen_size(VALUE self, VALUE rows, VALUE columns)
{
    rb_secure(4);
    rl_set_screen_size(NUM2INT(rows), NUM2INT(columns));
    return self;
}
special_prefixes → string click to toggle source

Gets the list of characters that are word break characters, but should be left in text when it is passed to the completion function.

See GNU Readline's rl_special_prefixes variable.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_get_special_prefixes(VALUE self)
{
    VALUE str;
    rb_secure(4);
    if (rl_special_prefixes == NULL) return Qnil;
    str = rb_ivar_get(mReadline, id_special_prefixes);
    if (!NIL_P(str)) {
        str = rb_str_dup_frozen(str);
        RBASIC(str)->klass = rb_cString;
    }
    return str;
}
special_prefixes = string click to toggle source

Sets the list of characters that are word break characters, but should be left in text when it is passed to the completion function. Programs can use this to help determine what kind of completing to do. For instance, Bash sets this variable to “$@” so that it can complete shell variables and hostnames.

See GNU Readline's rl_special_prefixes variable.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_set_special_prefixes(VALUE self, VALUE str)
{
    rb_secure(4);
    if (!NIL_P(str)) {
        OutputStringValue(str);
        str = rb_str_dup_frozen(str);
        RBASIC(str)->klass = 0;
    }
    rb_ivar_set(mReadline, id_special_prefixes, str);
    if (NIL_P(str)) {
        rl_special_prefixes = NULL;
    }
    else {
        rl_special_prefixes = RSTRING_PTR(str);
    }
    return self;
}
vi_editing_mode → nil click to toggle source

Specifies VI editing mode. See the manual of GNU Readline for details of VI editing mode.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_vi_editing_mode(VALUE self)
{
    rb_secure(4);
    rl_vi_editing_mode(1,0);
    return Qnil;
}
vi_editing_mode? → bool click to toggle source

Returns true if vi mode is active. Returns false if not.

Raises NotImplementedError if the using readline library does not support.

Raises SecurityError exception if $SAFE is 4.

static VALUE
readline_s_vi_editing_mode_p(VALUE self)
{
    rb_secure(4);
    return rl_editing_mode == 0 ? Qtrue : Qfalse;
}


class Regexp - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Regexp

Regexp serialization/deserialization

In Files

  • ext/json/lib/json/add/regexp.rb

Parent

Object

Public Class Methods

json_create(object) click to toggle source

Deserializes JSON string by constructing new Regexp object with source s (Regexp or String) and options o serialized by to_json

# File ext/json/lib/json/add/regexp.rb, line 11
def self.json_create(object)
  new(object['s'], object['o'])
end

Public Instance Methods

as_json(*) click to toggle source

Returns a hash, that will be turned into a JSON object and represent this object.

# File ext/json/lib/json/add/regexp.rb, line 17
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'o'            => options,
    's'            => source,
  }
end
to_json(*) click to toggle source

Stores class name (Regexp) with options o and source s (Regexp or String) as JSON string

# File ext/json/lib/json/add/regexp.rb, line 27
def to_json(*)
  as_json.to_json
end


class Resolv - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv

Resolv is a thread-aware DNS resolver library written in Ruby. Resolv can handle multiple DNS requests concurrently without blocking the entire ruby interpreter.

See also resolv-replace.rb to replace the libc resolver with Resolv.

Resolv can look up various DNS resources using the DNS module directly.

Examples:

p Resolv.getaddress "www.ruby-lang.org"
p Resolv.getname "210.251.121.214"

Resolv::DNS.open do |dns|
  ress = dns.getresources "www.ruby-lang.org", Resolv::DNS::Resource::IN::A
  p ress.map { |r| r.address }
  ress = dns.getresources "ruby-lang.org", Resolv::DNS::Resource::IN::MX
  p ress.map { |r| [r.exchange.to_s, r.preference] }
end

Bugs

  • NIS is not supported.

  • /etc/nsswitch.conf is not supported.

In Files

  • lib/resolv.rb

Parent

Object

Constants

AddressRegex

Address Regexp to use for matching IP addresses.

DefaultResolver

Default resolver to use for Resolv class methods.

Public Class Methods

each_address(name, &block) click to toggle source

Iterates over all IP addresses for name.

# File lib/resolv.rb, line 56
def self.each_address(name, &block)
  DefaultResolver.each_address(name, &block)
end
each_name(address, &proc) click to toggle source

Iterates over all hostnames for address.

# File lib/resolv.rb, line 77
def self.each_name(address, &proc)
  DefaultResolver.each_name(address, &proc)
end
getaddress(name) click to toggle source

Looks up the first IP address for name.

# File lib/resolv.rb, line 42
def self.getaddress(name)
  DefaultResolver.getaddress(name)
end
getaddresses(name) click to toggle source

Looks up all IP address for name.

# File lib/resolv.rb, line 49
def self.getaddresses(name)
  DefaultResolver.getaddresses(name)
end
getname(address) click to toggle source

Looks up the hostname of address.

# File lib/resolv.rb, line 63
def self.getname(address)
  DefaultResolver.getname(address)
end
getnames(address) click to toggle source

Looks up all hostnames for address.

# File lib/resolv.rb, line 70
def self.getnames(address)
  DefaultResolver.getnames(address)
end
new(resolvers=[Hosts.new, DNS.new]) click to toggle source

Creates a new Resolv using resolvers.

# File lib/resolv.rb, line 84
def initialize(resolvers=[Hosts.new, DNS.new])
  @resolvers = resolvers
end

Public Instance Methods

each_address(name) { |name| ... } click to toggle source

Iterates over all IP addresses for name.

# File lib/resolv.rb, line 108
def each_address(name)
  if AddressRegex =~ name
    yield name
    return
  end
  yielded = false
  @resolvers.each {|r|
    r.each_address(name) {|address|
      yield address.to_s
      yielded = true
    }
    return if yielded
  }
end
each_name(address) { |name| ... } click to toggle source

Iterates over all hostnames for address.

# File lib/resolv.rb, line 143
def each_name(address)
  yielded = false
  @resolvers.each {|r|
    r.each_name(address) {|name|
      yield name.to_s
      yielded = true
    }
    return if yielded
  }
end
getaddress(name) click to toggle source

Looks up the first IP address for name.

# File lib/resolv.rb, line 91
def getaddress(name)
  each_address(name) {|address| return address}
  raise ResolvError.new("no address for #{name}")
end
getaddresses(name) click to toggle source

Looks up all IP address for name.

# File lib/resolv.rb, line 99
def getaddresses(name)
  ret = []
  each_address(name) {|address| ret << address}
  return ret
end
getname(address) click to toggle source

Looks up the hostname of address.

# File lib/resolv.rb, line 126
def getname(address)
  each_name(address) {|name| return name}
  raise ResolvError.new("no name for #{address}")
end
getnames(address) click to toggle source

Looks up all hostnames for address.

# File lib/resolv.rb, line 134
def getnames(address)
  ret = []
  each_name(address) {|name| ret << name}
  return ret
end


class Resolv::DNS - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS

Resolv::DNS is a DNS stub resolver.

Information taken from the following places:

  • STD0013

  • RFC 1035

  • ftp.isi.edu/in-notes/iana/assignments/dns-parameters

  • etc.

In Files

  • lib/resolv.rb

Parent

Object

Constants

Port

Default DNS Port

UDPSize

Default DNS UDP packet size

Public Class Methods

new(config_info=nil) click to toggle source

Creates a new DNS resolver.

config_info can be:

nil

Uses /etc/resolv.conf.

String

Path to a file using /etc/resolv.conf's format.

Hash

Must contain :nameserver, :search and :ndots keys.

:nameserver_port can be used to specify port number of nameserver address.

The value of :nameserver should be an address string or an array of address strings.

  • :nameserver => '8.8.8.8'

  • :nameserver => ['8.8.8.8', '8.8.4.4']

The value of :nameserver_port should be an array of pair of nameserver address and port number.

  • :nameserver_port => [['8.8.8.8', 53], ['8.8.4.4', 53]]

Example:

Resolv::DNS.new(:nameserver => ['210.251.121.21'],
                :search => ['ruby-lang.org'],
                :ndots => 1)

# File lib/resolv.rb, line 333
def initialize(config_info=nil)
  @mutex = Mutex.new
  @config = Config.new(config_info)
  @initialized = nil
end
open(*args) { |dns| ... } click to toggle source

Creates a new DNS resolver. See ::new for argument details.

Yields the created DNS resolver to the block, if given, otherwise returns it.

# File lib/resolv.rb, line 298
def self.open(*args)
  dns = new(*args)
  return dns unless block_given?
  begin
    yield dns
  ensure
    dns.close
  end
end

Public Instance Methods

close() click to toggle source

Closes the DNS resolver.

# File lib/resolv.rb, line 367
def close
  @mutex.synchronize {
    if @initialized
      @initialized = false
    end
  }
end
each_address(name) { |address| ... } click to toggle source

Iterates over all IP addresses for name retrieved from the DNS resolver.

name can be a Resolv::DNS::Name or a String. Retrieved addresses will be a Resolv::IPv4 or Resolv::IPv6

# File lib/resolv.rb, line 405
def each_address(name)
  each_resource(name, Resource::IN::A) {|resource| yield resource.address}
  if use_ipv6?
    each_resource(name, Resource::IN::AAAA) {|resource| yield resource.address}
  end
end
each_name(address) { |name| ... } click to toggle source

Iterates over all hostnames for address retrieved from the DNS resolver.

address must be a Resolv::IPv4, Resolv::IPv6 or a String. Retrieved names will be Resolv::DNS::Name instances.

# File lib/resolv.rb, line 452
def each_name(address)
  case address
  when Name
    ptr = address
  when IPv4::Regex
    ptr = IPv4.create(address).to_name
  when IPv6::Regex
    ptr = IPv6.create(address).to_name
  else
    raise ResolvError.new("cannot interpret as address: #{address}")
  end
  each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}
end
each_resource(name, typeclass, &proc) click to toggle source

Iterates over all typeclass DNS resources for name. See getresource for argument details.

# File lib/resolv.rb, line 508
def each_resource(name, typeclass, &proc)
  lazy_initialize
  requester = make_udp_requester
  senders = {}
  begin
    @config.resolv(name) {|candidate, tout, nameserver, port|
      msg = Message.new
      msg.rd = 1
      msg.add_question(candidate, typeclass)
      unless sender = senders[[candidate, nameserver, port]]
        sender = requester.sender(msg, candidate, nameserver, port)
        next if !sender
        senders[[candidate, nameserver, port]] = sender
      end
      reply, reply_name = requester.request(sender, tout)
      case reply.rcode
      when RCode::NoError
        if reply.tc == 1 and not Requester::TCP === requester
          requester.close
          # Retry via TCP:
          requester = make_tcp_requester(nameserver, port)
          senders = {}
          # This will use TCP for all remaining candidates (assuming the
          # current candidate does not already respond successfully via
          # TCP).  This makes sense because we already know the full
          # response will not fit in an untruncated UDP packet.
          redo
        else
          extract_resources(reply, reply_name, typeclass, &proc)
        end
        return
      when RCode::NXDomain
        raise Config::NXDomain.new(reply_name.to_s)
      else
        raise Config::OtherResolvError.new(reply_name.to_s)
      end
    }
  ensure
    requester.close
  end
end
getaddress(name) click to toggle source

Gets the IP address of name from the DNS resolver.

name can be a Resolv::DNS::Name or a String. Retrieved address will be a Resolv::IPv4 or Resolv::IPv6

# File lib/resolv.rb, line 381
def getaddress(name)
  each_address(name) {|address| return address}
  raise ResolvError.new("DNS result has no information for #{name}")
end
getaddresses(name) click to toggle source

Gets all IP addresses for name from the DNS resolver.

name can be a Resolv::DNS::Name or a String. Retrieved addresses will be a Resolv::IPv4 or Resolv::IPv6

# File lib/resolv.rb, line 392
def getaddresses(name)
  ret = []
  each_address(name) {|address| ret << address}
  return ret
end
getname(address) click to toggle source

Gets the hostname for address from the DNS resolver.

address must be a Resolv::IPv4, Resolv::IPv6 or a String. Retrieved name will be a Resolv::DNS::Name.

# File lib/resolv.rb, line 428
def getname(address)
  each_name(address) {|name| return name}
  raise ResolvError.new("DNS result has no information for #{address}")
end
getnames(address) click to toggle source

Gets all hostnames for address from the DNS resolver.

address must be a Resolv::IPv4, Resolv::IPv6 or a String. Retrieved names will be Resolv::DNS::Name instances.

# File lib/resolv.rb, line 439
def getnames(address)
  ret = []
  each_name(address) {|name| ret << name}
  return ret
end
getresource(name, typeclass) click to toggle source

Look up the typeclass DNS resource of name.

name must be a Resolv::DNS::Name or a String.

typeclass should be one of the following:

  • Resolv::DNS::Resource::IN::A

  • Resolv::DNS::Resource::IN::AAAA

  • Resolv::DNS::Resource::IN::ANY

  • Resolv::DNS::Resource::IN::CNAME

  • Resolv::DNS::Resource::IN::HINFO

  • Resolv::DNS::Resource::IN::MINFO

  • Resolv::DNS::Resource::IN::MX

  • Resolv::DNS::Resource::IN::NS

  • Resolv::DNS::Resource::IN::PTR

  • Resolv::DNS::Resource::IN::SOA

  • Resolv::DNS::Resource::IN::TXT

  • Resolv::DNS::Resource::IN::WKS

Returned resource is represented as a Resolv::DNS::Resource instance, i.e. Resolv::DNS::Resource::IN::A.

# File lib/resolv.rb, line 489
def getresource(name, typeclass)
  each_resource(name, typeclass) {|resource| return resource}
  raise ResolvError.new("DNS result has no information for #{name}")
end
getresources(name, typeclass) click to toggle source

Looks up all typeclass DNS resources for name. See getresource for argument details.

# File lib/resolv.rb, line 498
def getresources(name, typeclass)
  ret = []
  each_resource(name, typeclass) {|resource| ret << resource}
  return ret
end
timeouts=(values) click to toggle source

Sets the resolver timeouts. This may be a single positive number or an array of positive numbers representing timeouts in seconds. If an array is specified, a DNS request will retry and wait for each successive interval in the array until a successful response is received. Specifying nil reverts to the default timeouts:

5, second = 5 * 2 / nameserver_count, 2 * second, 4 * second

Example:

dns.timeouts = 3
# File lib/resolv.rb, line 350
def timeouts=(values)
  @config.timeouts = values
end


class Resolv::DNS::Config - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Config

In Files

  • lib/resolv.rb

Parent

Object


class Resolv::DNS::Config::NXDomain - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Config::NXDomain

Indicates no such domain was found.

In Files

  • lib/resolv.rb

Parent

Resolv::ResolvError


class Resolv::DNS::Config::OtherResolvError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Config::OtherResolvError

Indicates some other unhandled resolver error was encountered.

In Files

  • lib/resolv.rb

Parent

Resolv::ResolvError


class Resolv::DNS::DecodeError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::DecodeError

Indicates that the DNS response was unable to be decoded.

In Files

  • lib/resolv.rb

Parent

StandardError


class Resolv::DNS::EncodeError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::EncodeError

Indicates that the DNS request was unable to be encoded.

In Files

  • lib/resolv.rb

Parent

StandardError


class Resolv::DNS::Name - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Name

A representation of a DNS name.

In Files

  • lib/resolv.rb

Parent

Object

Public Class Methods

create(arg) click to toggle source

Creates a new DNS name from arg. arg can be:

Name

returns arg.

String

Creates a new Name.

# File lib/resolv.rb, line 1179
def self.create(arg)
  case arg
  when Name
    return arg
  when String
    return Name.new(Label.split(arg), /\.\z/ =~ arg ? true : false)
  else
    raise ArgumentError.new("cannot interpret as DNS name: #{arg.inspect}")
  end
end

Public Instance Methods

absolute?() click to toggle source

True if this name is absolute.

# File lib/resolv.rb, line 1202
def absolute?
  return @absolute
end
subdomain_of?(other) click to toggle source

Returns true if other is a subdomain.

Example:

domain = Resolv::DNS::Name.create("y.z")
p Resolv::DNS::Name.create("w.x.y.z").subdomain_of?(domain) #=> true
p Resolv::DNS::Name.create("x.y.z").subdomain_of?(domain) #=> true
p Resolv::DNS::Name.create("y.z").subdomain_of?(domain) #=> false
p Resolv::DNS::Name.create("z").subdomain_of?(domain) #=> false
p Resolv::DNS::Name.create("x.y.z.").subdomain_of?(domain) #=> false
p Resolv::DNS::Name.create("w.z").subdomain_of?(domain) #=> false

# File lib/resolv.rb, line 1227
def subdomain_of?(other)
  raise ArgumentError, "not a domain name: #{other.inspect}" unless Name === other
  return false if @absolute != other.absolute?
  other_len = other.length
  return false if @labels.length <= other_len
  return @labels[-other_len, other_len] == other.to_a
end
to_s() click to toggle source

returns the domain name as a string.

The domain name doesn't have a trailing dot even if the name object is absolute.

Example:

p Resolv::DNS::Name.create("x.y.z.").to_s #=> "x.y.z"
p Resolv::DNS::Name.create("x.y.z").to_s #=> "x.y.z"

# File lib/resolv.rb, line 1262
def to_s
  return @labels.join('.')
end


class Resolv::DNS::Query - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Query

A DNS query abstract class.

In Files

  • lib/resolv.rb

Parent

Object


class Resolv::DNS::Requester - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Requester

In Files

  • lib/resolv.rb

Parent

Object


class Resolv::DNS::Requester::RequestError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Requester::RequestError

Indicates a problem with the DNS request.

In Files

  • lib/resolv.rb

Parent

StandardError


class Resolv::DNS::Resource - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource

A DNS resource abstract class.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Query

Attributes

ttl[R]

Remaining Time To Live for this Resource.


class Resolv::DNS::Resource::ANY - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::ANY

A Query type requesting any RR.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Query


class Resolv::DNS::Resource::CNAME - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::CNAME

The canonical name for an alias.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource::DomainName


class Resolv::DNS::Resource::DomainName - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::DomainName

Domain Name resource abstract class.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource

Attributes

name[R]

The name of this DomainName.

Public Class Methods

new(name) click to toggle source

Creates a new DomainName from name.

# File lib/resolv.rb, line 1705
def initialize(name)
  @name = name
end


class Resolv::DNS::Resource::Generic - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::Generic

A generic resource abstract class.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource

Attributes

data[R]

Data for this generic resource.

Public Class Methods

new(data) click to toggle source

Creates a new generic resource.

# File lib/resolv.rb, line 1670
def initialize(data)
  @data = data
end


class Resolv::DNS::Resource::HINFO - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::HINFO

Host Information resource.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource

Attributes

cpu[R]

CPU architecture for this resource.

os[R]

Operating system for this resource.

Public Class Methods

new(cpu, os) click to toggle source

Creates a new HINFO running os on cpu.

# File lib/resolv.rb, line 1832
def initialize(cpu, os)
  @cpu = cpu
  @os = os
end


module Resolv::DNS::Resource::IN - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Resolv::DNS::Resource::IN

module IN contains ARPA Internet specific RRs.

In Files

  • lib/resolv.rb


class Resolv::DNS::Resource::IN::A - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::IN::A

IPv4 Address resource

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource

Constants

ClassValue
TypeValue

Attributes

address[R]

The Resolv::IPv4 address for this A.

Public Class Methods

new(address) click to toggle source

Creates a new A for address.

# File lib/resolv.rb, line 2001
def initialize(address)
  @address = IPv4.create(address)
end


class Resolv::DNS::Resource::IN::AAAA - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::IN::AAAA

An IPv6 address record.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource

Constants

ClassValue
TypeValue

Attributes

address[R]

The Resolv::IPv6 address for this AAAA.

Public Class Methods

new(address) click to toggle source

Creates a new AAAA for address.

# File lib/resolv.rb, line 2078
def initialize(address)
  @address = IPv6.create(address)
end


class Resolv::DNS::Resource::IN::SRV - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::IN::SRV

SRV resource record defined in RFC 2782

These records identify the hostname and port that a service is available at.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource

Constants

ClassValue
TypeValue

Attributes

port[R]

The port on this target host of this service.

The range is 0-65535.

priority[R]

The priority of this target host.

A client MUST attempt to contact the target host with the lowest-numbered priority it can reach; target hosts with the same priority SHOULD be tried in an order defined by the weight field. The range is 0-65535. Note that it is not widely implemented and should be set to zero.

target[R]

The domain name of the target host.

A target of “.” means that the service is decidedly not available at this domain.

weight[R]

A server selection mechanism.

The weight field specifies a relative weight for entries with the same priority. Larger weights SHOULD be given a proportionately higher probability of being selected. The range of this number is 0-65535. Domain administrators SHOULD use Weight 0 when there isn't any server selection to do, to make the RR easier to read for humans (less noisy). Note that it is not widely implemented and should be set to zero.

Public Class Methods

new(priority, weight, port, target) click to toggle source

Create a SRV resource record.

See the documentation for priority, weight, port and target for priority, weight, +port and target respectively.

# File lib/resolv.rb, line 2112
def initialize(priority, weight, port, target)
  @priority = priority.to_int
  @weight = weight.to_int
  @port = port.to_int
  @target = Name.create(target)
end


class Resolv::DNS::Resource::IN::WKS - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::IN::WKS

Well Known Service resource.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource

Constants

ClassValue
TypeValue

Attributes

address[R]

The host these services run on.

bitmap[R]

A bit map of enabled services on this host.

If protocol is 6 (TCP) then the 26th bit corresponds to the SMTP service (port 25). If this bit is set, then an SMTP server should be listening on TCP port 25; if zero, SMTP service is not supported.

protocol[R]

IP protocol number for these services.

Public Class Methods

new(address, protocol, bitmap) click to toggle source
# File lib/resolv.rb, line 2027
def initialize(address, protocol, bitmap)
  @address = IPv4.create(address)
  @protocol = protocol
  @bitmap = bitmap
end


class Resolv::DNS::Resource::MINFO - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::MINFO

Mailing list or mailbox information.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource

Attributes

emailbx[R]

Mailbox to use for error messages related to the mail list or mailbox.

rmailbx[R]

Domain name responsible for this mail list or mailbox.

Public Class Methods

new(rmailbx, emailbx) click to toggle source
# File lib/resolv.rb, line 1866
def initialize(rmailbx, emailbx)
  @rmailbx = rmailbx
  @emailbx = emailbx
end


class Resolv::DNS::Resource::MX - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::MX

Mail Exchanger resource.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource

Attributes

exchange[R]

The host of this MX.

preference[R]

The preference for this MX.

Public Class Methods

new(preference, exchange) click to toggle source

Creates a new MX record with preference, accepting mail at exchange.

# File lib/resolv.rb, line 1904
def initialize(preference, exchange)
  @preference = preference
  @exchange = exchange
end


class Resolv::DNS::Resource::NS - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::NS

An authoritative name server.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource::DomainName


class Resolv::DNS::Resource::PTR - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::PTR

A Pointer to another DNS name.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource::DomainName


class Resolv::DNS::Resource::SOA - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::SOA

Start Of Authority resource.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource

Attributes

expire[R]

Time in seconds that a secondary name server is to use the data before refreshing from the primary name server.

minimum[R]

The minimum number of seconds to be used for TTL values in RRs.

mname[R]

Name of the host where the master zone file for this zone resides.

refresh[R]

How often, in seconds, a secondary name server is to check for updates from the primary name server.

retry[R]

How often, in seconds, a secondary name server is to retry after a failure to check for a refresh.

rname[R]

The person responsible for this domain name.

serial[R]

The version number of the zone file.

Public Class Methods

new(mname, rname, serial, refresh, retry_, expire, minimum) click to toggle source

Creates a new SOA record. See the attr documentation for the details of each argument.

# File lib/resolv.rb, line 1752
def initialize(mname, rname, serial, refresh, retry_, expire, minimum)
  @mname = mname
  @rname = rname
  @serial = serial
  @refresh = refresh
  @retry = retry_
  @expire = expire
  @minimum = minimum
end


class Resolv::DNS::Resource::TXT - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::DNS::Resource::TXT

Unstructured text resource.

In Files

  • lib/resolv.rb

Parent

Resolv::DNS::Resource

Attributes

strings[R]

Returns an Array of Strings for this TXT record.

Public Class Methods

new(first_string, *rest_strings) click to toggle source
# File lib/resolv.rb, line 1938
def initialize(first_string, *rest_strings)
  @strings = [first_string, *rest_strings]
end

Public Instance Methods

data() click to toggle source

Returns the concatenated string from strings.

# File lib/resolv.rb, line 1950
def data
  @strings.join("")
end


class Resolv::Hosts - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::Hosts

Resolv::Hosts is a hostname resolver that uses the system hosts file.

In Files

  • lib/resolv.rb

Parent

Object

Constants

DefaultFileName

Public Class Methods

new(filename = DefaultFileName) click to toggle source

Creates a new Resolv::Hosts, using filename for its data source.

# File lib/resolv.rb, line 178
def initialize(filename = DefaultFileName)
  @filename = filename
  @mutex = Mutex.new
  @initialized = nil
end

Public Instance Methods

each_address(name, &proc) click to toggle source

Iterates over all IP addresses for name retrieved from the hosts file.

# File lib/resolv.rb, line 235
def each_address(name, &proc)
  lazy_initialize
  if @name2addr.include?(name)
    @name2addr[name].each(&proc)
  end
end
each_name(address, &proc) click to toggle source

Iterates over all hostnames for address retrieved from the hosts file.

# File lib/resolv.rb, line 262
def each_name(address, &proc)
  lazy_initialize
  if @addr2name.include?(address)
    @addr2name[address].each(&proc)
  end
end
getaddress(name) click to toggle source

Gets the IP address of name from the hosts file.

# File lib/resolv.rb, line 218
def getaddress(name)
  each_address(name) {|address| return address}
  raise ResolvError.new("#{@filename} has no name: #{name}")
end
getaddresses(name) click to toggle source

Gets all IP addresses for name from the hosts file.

# File lib/resolv.rb, line 226
def getaddresses(name)
  ret = []
  each_address(name) {|address| ret << address}
  return ret
end
getname(address) click to toggle source

Gets the hostname of address from the hosts file.

# File lib/resolv.rb, line 245
def getname(address)
  each_name(address) {|name| return name}
  raise ResolvError.new("#{@filename} has no address: #{address}")
end
getnames(address) click to toggle source

Gets all hostnames for address from the hosts file.

# File lib/resolv.rb, line 253
def getnames(address)
  ret = []
  each_name(address) {|name| ret << name}
  return ret
end


class Resolv::IPv4 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::IPv4

A Resolv::DNS IPv4 address.

In Files

  • lib/resolv.rb

Parent

Object

Constants

Regex
Regex256

Regular expression IPv4 addresses must match.

Attributes

address[R]

The raw IPv4 address as a String.

Public Class Methods

create(arg) click to toggle source
# File lib/resolv.rb, line 2187
def self.create(arg)
  case arg
  when IPv4
    return arg
  when Regex
    if (0..255) === (a = $1.to_i) &&
       (0..255) === (b = $2.to_i) &&
       (0..255) === (c = $3.to_i) &&
       (0..255) === (d = $4.to_i)
      return self.new([a, b, c, d].pack("CCCC"))
    else
      raise ArgumentError.new("IPv4 address with invalid value: " + arg)
    end
  else
    raise ArgumentError.new("cannot interpret as IPv4 address: #{arg.inspect}")
  end
end

Public Instance Methods

to_name() click to toggle source

Turns this IPv4 address into a Resolv::DNS::Name.

# File lib/resolv.rb, line 2234
def to_name
  return DNS::Name.create(
    '%d.%d.%d.%d.in-addr.arpa.' % @address.unpack('CCCC').reverse)
end


class Resolv::IPv6 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::IPv6

A Resolv::DNS IPv6 address.

In Files

  • lib/resolv.rb

Parent

Object

Constants

Regex

A composite IPv6 address Regexp.

Regex_6Hex4Dec

IPv4 mapped IPv6 address format a:b:c:d:e:f:w.x.y.z

Regex_8Hex

IPv6 address format a:b:c:d:e:f:g:h

Regex_CompressedHex

Compressed IPv6 address format a::b

Regex_CompressedHex4Dec

Compressed IPv4 mapped IPv6 address format a::b:w.x.y.z

Attributes

address[R]

The raw IPv6 address as a String.

Public Class Methods

create(arg) click to toggle source

Creates a new IPv6 address from arg which may be:

IPv6

returns arg.

String

arg must match one of the IPv6::Regex* constants

# File lib/resolv.rb, line 2304
def self.create(arg)
  case arg
  when IPv6
    return arg
  when String
    address = ''
    if Regex_8Hex =~ arg
      arg.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
    elsif Regex_CompressedHex =~ arg
      prefix = $1
      suffix = $2
      a1 = ''
      a2 = ''
      prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
      suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
      omitlen = 16 - a1.length - a2.length
      address << a1 << "\00"" * omitlen << a2
    elsif Regex_6Hex4Dec =~ arg
      prefix, a, b, c, d = $1, $2.to_i, $3.to_i, $4.to_i, $5.to_i
      if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
        prefix.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
        address << [a, b, c, d].pack('CCCC')
      else
        raise ArgumentError.new("not numeric IPv6 address: " + arg)
      end
    elsif Regex_CompressedHex4Dec =~ arg
      prefix, suffix, a, b, c, d = $1, $2, $3.to_i, $4.to_i, $5.to_i, $6.to_i
      if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
        a1 = ''
        a2 = ''
        prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
        suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
        omitlen = 12 - a1.length - a2.length
        address << a1 << "\00"" * omitlen << a2 << [a, b, c, d].pack('CCCC')
      else
        raise ArgumentError.new("not numeric IPv6 address: " + arg)
      end
    else
      raise ArgumentError.new("not numeric IPv6 address: " + arg)
    end
    return IPv6.new(address)
  else
    raise ArgumentError.new("cannot interpret as IPv6 address: #{arg.inspect}")
  end
end

Public Instance Methods

to_name() click to toggle source

Turns this IPv6 address into a Resolv::DNS::Name.

# File lib/resolv.rb, line 2379
def to_name
  return DNS::Name.new(
    @address.unpack("H32")[0].split(//).reverse + ['ip6', 'arpa'])
end


class Resolv::ResolvError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::ResolvError

Indicates a failure to resolve a name or address.

In Files

  • lib/resolv.rb

Parent

StandardError


class Resolv::ResolvTimeout - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Resolv::ResolvTimeout

Indicates a timeout resolving a name or address.

In Files

  • lib/resolv.rb

Parent

Timeout::Error


module Rinda - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Rinda

A module to implement the Linda distributed computing paradigm in Ruby.

Rinda is part of DRb (dRuby).

Example(s)

See the sample/drb/ directory in the Ruby distribution, from 1.8.2 onwards.

In Files

  • lib/rinda/rinda.rb
  • lib/rinda/ring.rb
  • lib/rinda/tuplespace.rb

Constants

Ring_PORT

The default port Ring discovery will use.


class Rinda::DRbObjectTemplate - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::DRbObjectTemplate

Documentation?

In Files

  • lib/rinda/rinda.rb

Parent

Object

Public Class Methods

new(uri=nil, ref=nil) click to toggle source

Creates a new DRbObjectTemplate that will match against uri and ref.

# File lib/rinda/rinda.rb, line 183
def initialize(uri=nil, ref=nil)
  @drb_uri = uri
  @drb_ref = ref
end

Public Instance Methods

===(ro) click to toggle source

This DRbObjectTemplate matches ro if the remote object's drburi and drbref are the same. nil is used as a wildcard.

# File lib/rinda/rinda.rb, line 192
def ===(ro)
  return true if super(ro)
  unless @drb_uri.nil?
    return false unless (@drb_uri === ro.__drburi rescue false)
  end
  unless @drb_ref.nil?
    return false unless (@drb_ref === ro.__drbref rescue false)
  end
  true
end


class Rinda::InvalidHashTupleKey - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::InvalidHashTupleKey

Raised when a hash-based tuple has an invalid key.

In Files

  • lib/rinda/rinda.rb

Parent

Rinda::RindaError


class Rinda::NotifyTemplateEntry - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::NotifyTemplateEntry

A NotifyTemplateEntry is returned by Rinda::TupleSpace#notify and is notified of TupleSpace changes. You may receive either your subscribed event or the 'close' event when iterating over notifications.

See TupleSpace#notify_event for valid notification types.

Example

ts = Rinda::TupleSpace.new
observer = ts.notify 'write', [nil]

Thread.start do
  observer.each { |t| p t }
end

3.times { |i| ts.write [i] }

Outputs:

['write', [0]]
['write', [1]]
['write', [2]]

In Files

  • lib/rinda/tuplespace.rb

Parent

Rinda::TemplateEntry

Public Class Methods

new(place, event, tuple, expires=nil) click to toggle source

Creates a new NotifyTemplateEntry that watches place for +event+s that match tuple.

# File lib/rinda/tuplespace.rb, line 246
def initialize(place, event, tuple, expires=nil)
  ary = [event, Rinda::Template.new(tuple)]
  super(ary, expires)
  @queue = Queue.new
  @done = false
end

Public Instance Methods

each() { |event, tuple| ... } click to toggle source

Yields event/tuple pairs until this NotifyTemplateEntry expires.

# File lib/rinda/tuplespace.rb, line 274
def each # :yields: event, tuple
  while !@done
    it = pop
    yield(it)
  end
rescue
ensure
  cancel
end
notify(ev) click to toggle source

Called by TupleSpace to notify this NotifyTemplateEntry of a new event.

# File lib/rinda/tuplespace.rb, line 256
def notify(ev)
  @queue.push(ev)
end
pop() click to toggle source

Retrieves a notification. Raises RequestExpiredError when this NotifyTemplateEntry expires.

# File lib/rinda/tuplespace.rb, line 264
def pop
  raise RequestExpiredError if @done
  it = @queue.pop
  @done = true if it[0] == 'close'
  return it
end


class Rinda::RequestCanceledError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::RequestCanceledError

Raised when trying to use a canceled tuple.

In Files

  • lib/rinda/rinda.rb

Parent

ThreadError


class Rinda::RequestExpiredError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::RequestExpiredError

Raised when trying to use an expired tuple.

In Files

  • lib/rinda/rinda.rb

Parent

ThreadError


class Rinda::RindaError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::RindaError

Rinda error base class

In Files

  • lib/rinda/rinda.rb

Parent

RuntimeError


class Rinda::RingFinger - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::RingFinger

RingFinger is used by RingServer clients to discover the RingServer's TupleSpace. Typically, all a client needs to do is call ::primary to retrieve the remote TupleSpace, which it can then begin using.

In Files

  • lib/rinda/ring.rb

Parent

Object

Attributes

broadcast_list[RW]

The list of addresses where RingFinger will send query packets.

port[RW]

The port that RingFinger will send query packets to.

primary[RW]

Contain the first advertised TupleSpace after #lookup_ring_any is called.

Public Class Methods

finger() click to toggle source

Creates a singleton RingFinger and looks for a RingServer. Returns the created RingFinger.

# File lib/rinda/ring.rb, line 106
def self.finger
  unless @@finger
    @@finger = self.new
    @@finger.lookup_ring_any
  end
  @@finger
end
new(broadcast_list=@@broadcast_list, port=Ring_PORT) click to toggle source

Creates a new RingFinger that will look for RingServers at port on the addresses in broadcast_list.

# File lib/rinda/ring.rb, line 147
def initialize(broadcast_list=@@broadcast_list, port=Ring_PORT)
  @broadcast_list = broadcast_list || ['localhost']
  @port = port
  @primary = nil
  @rings = []
end
primary() click to toggle source

Returns the first advertised TupleSpace.

# File lib/rinda/ring.rb, line 117
def self.primary
  finger.primary
end
to_a() click to toggle source

Contains all discovered TupleSpaces except for the primary.

# File lib/rinda/ring.rb, line 124
def self.to_a
  finger.to_a
end

Public Instance Methods

each() { |primary| ... } click to toggle source

Iterates over all discovered TupleSpaces starting with the primary.

# File lib/rinda/ring.rb, line 164
def each
  lookup_ring_any unless @primary
  return unless @primary
  yield(@primary)
  @rings.each { |x| yield(x) }
end
lookup_ring(timeout=5, &block) click to toggle source

Looks up RingServers waiting timeout seconds. RingServers will be given block as a callback, which will be called with the remote TupleSpace.

# File lib/rinda/ring.rb, line 176
def lookup_ring(timeout=5, &block)
  return lookup_ring_any(timeout) unless block_given?

  msg = Marshal.dump([[:lookup_ring, DRbObject.new(block)], timeout])
  @broadcast_list.each do |it|
    soc = UDPSocket.open
    begin
      soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
      soc.send(msg, 0, it, @port)
    rescue
      nil
    ensure
      soc.close
    end
  end
  sleep(timeout)
end
lookup_ring_any(timeout=5) click to toggle source

Returns the first found remote TupleSpace. Any further recovered TupleSpaces can be found by calling to_a.

# File lib/rinda/ring.rb, line 198
def lookup_ring_any(timeout=5)
  queue = Queue.new

  Thread.new do
    self.lookup_ring(timeout) do |ts|
      queue.push(ts)
    end
    queue.push(nil)
  end

  @primary = queue.pop
  raise('RingNotFound') if @primary.nil?

  Thread.new do
    while it = queue.pop
      @rings.push(it)
    end
  end

  @primary
end
to_a() click to toggle source

Contains all discovered TupleSpaces except for the primary.

# File lib/rinda/ring.rb, line 157
def to_a
  @rings
end


class Rinda::RingProvider - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::RingProvider

RingProvider uses a RingServer advertised TupleSpace as a name service. TupleSpace clients can register themselves with the remote TupleSpace and look up other provided services via the remote TupleSpace.

Services are registered with a tuple of the format [:name, klass, DRbObject, description].

In Files

  • lib/rinda/ring.rb

Parent

Object

Public Class Methods

new(klass, front, desc, renewer = nil) click to toggle source

Creates a RingProvider that will provide a klass service running on front, with a description. renewer is optional.

# File lib/rinda/ring.rb, line 236
def initialize(klass, front, desc, renewer = nil)
  @tuple = [:name, klass, front, desc]
  @renewer = renewer || Rinda::SimpleRenewer.new
end

Public Instance Methods

provide() click to toggle source

Advertises this service on the primary remote TupleSpace.

# File lib/rinda/ring.rb, line 244
def provide
  ts = Rinda::RingFinger.primary
  ts.write(@tuple, @renewer)
end


class Rinda::RingServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::RingServer

A RingServer allows a Rinda::TupleSpace to be located via UDP broadcasts. Service location uses the following steps:

  1. A RingServer begins listening on the broadcast UDP address.

  2. A RingFinger sends a UDP packet containing the DRb URI where it will listen for a reply.

  3. The RingServer receives the UDP packet and connects back to the provided DRb URI with the DRb service.

In Files

  • lib/rinda/ring.rb

Parent

Object

Included Modules

  • DRb::DRbUndumped

Public Class Methods

new(ts, port=Ring_PORT) click to toggle source

Advertises ts on the UDP broadcast address at port.

# File lib/rinda/ring.rb, line 32
def initialize(ts, port=Ring_PORT)
  @ts = ts
  @soc = UDPSocket.open
  @soc.bind('', port)
  @w_service = write_service
  @r_service = reply_service
end

Public Instance Methods

do_reply() click to toggle source

Pulls lookup tuples out of the TupleSpace and sends their DRb object the address of the local TupleSpace.

# File lib/rinda/ring.rb, line 82
def do_reply
  tuple = @ts.take([:lookup_ring, DRbObject])
  Thread.new { tuple[1].call(@ts) rescue nil}
rescue
end
do_write(msg) click to toggle source

Extracts the response URI from msg and adds it to TupleSpace where it will be picked up by reply_service for notification.

# File lib/rinda/ring.rb, line 57
def do_write(msg)
  Thread.new do
    begin
      tuple, sec = Marshal.load(msg)
      @ts.write(tuple, sec)
    rescue
    end
  end
end
reply_service() click to toggle source

Creates a thread that notifies waiting clients from the TupleSpace.

# File lib/rinda/ring.rb, line 70
def reply_service
  Thread.new do
    loop do
      do_reply
    end
  end
end
write_service() click to toggle source

Creates a thread that picks up UDP packets and passes them to #do_write for decoding.

# File lib/rinda/ring.rb, line 44
def write_service
  Thread.new do
    loop do
      msg = @soc.recv(1024)
      do_write(msg)
    end
  end
end


class Rinda::SimpleRenewer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::SimpleRenewer

An SimpleRenewer allows a TupleSpace to check if a TupleEntry is still alive.

In Files

  • lib/rinda/rinda.rb

Parent

Object

Included Modules

  • DRb::DRbUndumped

Public Class Methods

new(sec=180) click to toggle source

Creates a new SimpleRenewer that keeps an object alive for another sec seconds.

# File lib/rinda/rinda.rb, line 270
def initialize(sec=180)
  @sec = sec
end

Public Instance Methods

renew() click to toggle source

Called by the TupleSpace to check if the object is still alive.

# File lib/rinda/rinda.rb, line 277
def renew
  @sec
end


class Rinda::Template - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::Template

Templates are used to match tuples in Rinda.

In Files

  • lib/rinda/rinda.rb

Parent

Rinda::Tuple

Public Instance Methods

===(tuple) click to toggle source

Alias for match.

# File lib/rinda/rinda.rb, line 169
def ===(tuple)
  match(tuple)
end
match(tuple) click to toggle source

Matches this template against tuple. The tuple must be the same size as the template. An element with a nil value in a template acts as a wildcard, matching any value in the corresponding position in the tuple. Elements of the template match the tuple if the are #== or #===.

Template.new([:foo, 5]).match   Tuple.new([:foo, 5]) # => true
Template.new([:foo, nil]).match Tuple.new([:foo, 5]) # => true
Template.new([String]).match    Tuple.new(['hello']) # => true

Template.new([:foo]).match      Tuple.new([:foo, 5]) # => false
Template.new([:foo, 6]).match   Tuple.new([:foo, 5]) # => false
Template.new([:foo, nil]).match Tuple.new([:foo])    # => false
Template.new([:foo, 6]).match   Tuple.new([:foo])    # => false

# File lib/rinda/rinda.rb, line 148
def match(tuple)
  return false unless tuple.respond_to?(:size)
  return false unless tuple.respond_to?(:fetch)
  return false unless self.size == tuple.size
  each do |k, v|
    begin
      it = tuple.fetch(k)
    rescue
      return false
    end
    next if v.nil?
    next if v == it
    next if v === it
    return false
  end
  return true
end


class Rinda::TemplateEntry - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::TemplateEntry

A TemplateEntry is a Template together with expiry and cancellation data.

In Files

  • lib/rinda/tuplespace.rb

Parent

Rinda::TupleEntry

Public Instance Methods

===(tuple) click to toggle source
Alias for: match
match(tuple) click to toggle source

Matches this TemplateEntry against tuple. See Rinda::Template#match for details on how a Template matches a Tuple.

# File lib/rinda/tuplespace.rb, line 168
def match(tuple)
  @tuple.match(tuple)
end
Also aliased as: ===


class Rinda::Tuple - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::Tuple

A tuple is the elementary object in Rinda programming. Tuples may be matched against templates if the tuple and the template are the same size.

In Files

  • lib/rinda/rinda.rb

Parent

Object

Public Class Methods

new(ary_or_hash) click to toggle source

Creates a new Tuple from ary_or_hash which must be an Array or Hash.

# File lib/rinda/rinda.rb, line 51
def initialize(ary_or_hash)
  if hash?(ary_or_hash)
    init_with_hash(ary_or_hash)
  else
    init_with_ary(ary_or_hash)
  end
end

Public Instance Methods

[](k) click to toggle source

Accessor method for elements of the tuple.

# File lib/rinda/rinda.rb, line 69
def [](k)
  @tuple[k]
end
each() { |k, v| ... } click to toggle source

Iterate through the tuple, yielding the index or key, and the value, thus ensuring arrays are iterated similarly to hashes.

# File lib/rinda/rinda.rb, line 84
def each # FIXME
  if Hash === @tuple
    @tuple.each { |k, v| yield(k, v) }
  else
    @tuple.each_with_index { |v, k| yield(k, v) }
  end
end
fetch(k) click to toggle source

Fetches item k from the tuple.

# File lib/rinda/rinda.rb, line 76
def fetch(k)
  @tuple.fetch(k)
end
size() click to toggle source

The number of elements in the tuple.

# File lib/rinda/rinda.rb, line 62
def size
  @tuple.size
end
value() click to toggle source

Return the tuple itself

# File lib/rinda/rinda.rb, line 94
def value
  @tuple
end


class Rinda::TupleBag - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::TupleBag

TupleBag is an unordered collection of tuples. It is the basis of Tuplespace.

In Files

  • lib/rinda/tuplespace.rb

Parent

Object

Public Instance Methods

delete(tuple) click to toggle source

Removes tuple from the TupleBag.

# File lib/rinda/tuplespace.rb, line 342
def delete(tuple)
  key = bin_key(tuple)
  bin = @hash[key]
  return nil unless bin
  bin.delete(tuple)
  @hash.delete(key) if bin.empty?
  tuple
end
delete_unless_alive() click to toggle source

Delete tuples which dead tuples from the TupleBag, returning the deleted tuples.

# File lib/rinda/tuplespace.rb, line 382
def delete_unless_alive
  deleted = []
  @hash.each do |key, bin|
    bin.delete_if do |tuple|
      if tuple.alive?
        false
      else
        deleted.push(tuple)
        true
      end
    end
  end
  deleted
end
find(template) click to toggle source

Finds a live tuple that matches template.

# File lib/rinda/tuplespace.rb, line 362
def find(template)
  bin_for_find(template).find do |tuple|
    tuple.alive? && template.match(tuple)
  end
end
find_all(template) click to toggle source

Finds all live tuples that match template.

# File lib/rinda/tuplespace.rb, line 353
def find_all(template)
  bin_for_find(template).find_all do |tuple|
    tuple.alive? && template.match(tuple)
  end
end
find_all_template(tuple) click to toggle source

Finds all tuples in the TupleBag which when treated as templates, match tuple and are alive.

# File lib/rinda/tuplespace.rb, line 372
def find_all_template(tuple)
  @enum.find_all do |template|
    template.alive? && template.match(tuple)
  end
end
has_expires?() click to toggle source

true if the TupleBag to see if it has any expired entries.

# File lib/rinda/tuplespace.rb, line 324
def has_expires?
  @enum.find do |tuple|
    tuple.expires
  end
end
push(tuple) click to toggle source

Add tuple to the TupleBag.

# File lib/rinda/tuplespace.rb, line 333
def push(tuple)
  key = bin_key(tuple)
  @hash[key] ||= TupleBin.new
  @hash[key].add(tuple)
end


class Rinda::TupleBag::TupleBin - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::TupleBag::TupleBin

In Files

  • lib/rinda/tuplespace.rb

Parent

Object

Public Class Methods

new() click to toggle source
# File lib/rinda/tuplespace.rb, line 295
def initialize
  @bin = []
end

Public Instance Methods

add(tuple) click to toggle source
# File lib/rinda/tuplespace.rb, line 299
def add(tuple)
  @bin.push(tuple)
end
delete(tuple) click to toggle source
# File lib/rinda/tuplespace.rb, line 303
def delete(tuple)
  idx = @bin.rindex(tuple)
  @bin.delete_at(idx) if idx
end
find() { |x| ... } click to toggle source
# File lib/rinda/tuplespace.rb, line 308
def find
  @bin.reverse_each do |x|
    return x if yield(x)
  end
  nil
end


class Rinda::TupleEntry - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::TupleEntry

A TupleEntry is a Tuple (i.e. a possible entry in some Tuplespace) together with expiry and cancellation data.

In Files

  • lib/rinda/tuplespace.rb

Parent

Object

Included Modules

  • DRb::DRbUndumped

Attributes

expires[RW]

Public Class Methods

new(ary, sec=nil) click to toggle source

Creates a TupleEntry based on ary with an optional renewer or expiry time sec.

A renewer must implement the renew method which returns a Numeric, nil, or true to indicate when the tuple has expired.

# File lib/rinda/tuplespace.rb, line 27
def initialize(ary, sec=nil)
  @cancel = false
  @expires = nil
  @tuple = make_tuple(ary)
  @renewer = nil
  renew(sec)
end

Public Instance Methods

[](key) click to toggle source

Retrieves key from the tuple.

# File lib/rinda/tuplespace.rb, line 111
def [](key)
  @tuple[key]
end
alive?() click to toggle source

A TupleEntry is dead when it is canceled or expired.

# File lib/rinda/tuplespace.rb, line 45
def alive?
  !canceled? && !expired?
end
cancel() click to toggle source

Marks this TupleEntry as canceled.

# File lib/rinda/tuplespace.rb, line 38
def cancel
  @cancel = true
end
canceled?() click to toggle source

Returns the canceled status.

# File lib/rinda/tuplespace.rb, line 58
def canceled?; @cancel; end
expired?() click to toggle source

Has this tuple expired? (true/false).

A tuple has expired when its expiry timer based on the sec argument to initialize runs out.

# File lib/rinda/tuplespace.rb, line 66
def expired?
  return true unless @expires
  return false if @expires > Time.now
  return true if @renewer.nil?
  renew(@renewer)
  return true unless @expires
  return @expires < Time.now
end
fetch(key) click to toggle source

Fetches key from the tuple.

# File lib/rinda/tuplespace.rb, line 118
def fetch(key)
  @tuple.fetch(key)
end
make_expires(sec=nil) click to toggle source

Returns an expiry Time based on sec which can be one of:

Numeric

sec seconds into the future

true

the expiry time is the start of 1970 (i.e. expired)

nil

it is Tue Jan 19 03:14:07 GMT Standard Time 2038 (i.e. when UNIX clocks will die)

# File lib/rinda/tuplespace.rb, line 97
def make_expires(sec=nil)
  case sec
  when Numeric
    Time.now + sec
  when true
    Time.at(1)
  when nil
    Time.at(2**31-1)
  end
end
make_tuple(ary) click to toggle source

Creates a Rinda::Tuple for ary.

# File lib/rinda/tuplespace.rb, line 132
def make_tuple(ary)
  Rinda::Tuple.new(ary)
end
renew(sec_or_renewer) click to toggle source

Reset the expiry time according to sec_or_renewer.

nil

it is set to expire in the far future.

true

it has expired.

Numeric

it will expire in that many seconds.

Otherwise the argument refers to some kind of renewer object which will reset its expiry time.

# File lib/rinda/tuplespace.rb, line 85
def renew(sec_or_renewer)
  sec, @renewer = get_renewer(sec_or_renewer)
  @expires = make_expires(sec)
end
size() click to toggle source

The size of the tuple.

# File lib/rinda/tuplespace.rb, line 125
def size
  @tuple.size
end
value() click to toggle source

Return the object which makes up the tuple itself: the Array or Hash.

# File lib/rinda/tuplespace.rb, line 53
def value; @tuple.value; end


class Rinda::TupleSpace - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::TupleSpace

The Tuplespace manages access to the tuples it contains, ensuring mutual exclusion requirements are met.

The sec option for the write, take, move, read and notify methods may either be a number of seconds or a Renewer object.

In Files

  • lib/rinda/tuplespace.rb

Parent

Object

Included Modules

  • DRb::DRbUndumped
  • MonitorMixin

Public Class Methods

new(period=60) click to toggle source

Creates a new TupleSpace. period is used to control how often to look for dead tuples after modifications to the TupleSpace.

If no dead tuples are found period seconds after the last modification, the TupleSpace will stop looking for dead tuples.

# File lib/rinda/tuplespace.rb, line 438
def initialize(period=60)
  super()
  @bag = TupleBag.new
  @read_waiter = TupleBag.new
  @take_waiter = TupleBag.new
  @notify_waiter = TupleBag.new
  @period = period
  @keeper = nil
end

Public Instance Methods

move(port, tuple, sec=nil) { |template| ... } click to toggle source

Moves tuple to port.

# File lib/rinda/tuplespace.rb, line 485
def move(port, tuple, sec=nil)
  template = WaitTemplateEntry.new(self, tuple, sec)
  yield(template) if block_given?
  synchronize do
    entry = @bag.find(template)
    if entry
      port.push(entry.value) if port
      @bag.delete(entry)
      notify_event('take', entry.value)
      return entry.value
    end
    raise RequestExpiredError if template.expired?

    begin
      @take_waiter.push(template)
      start_keeper if template.expires
      while true
        raise RequestCanceledError if template.canceled?
        raise RequestExpiredError if template.expired?
        entry = @bag.find(template)
        if entry
          port.push(entry.value) if port
          @bag.delete(entry)
          notify_event('take', entry.value)
          return entry.value
        end
        template.wait
      end
    ensure
      @take_waiter.delete(template)
    end
  end
end
notify(event, tuple, sec=nil) click to toggle source

Registers for notifications of event. Returns a NotifyTemplateEntry. See NotifyTemplateEntry for examples of how to listen for notifications.

event can be:

'write'

A tuple was added

'take'

A tuple was taken or moved

'delete'

A tuple was lost after being overwritten or expiring

The TupleSpace will also notify you of the 'close' event when the NotifyTemplateEntry has expired.

# File lib/rinda/tuplespace.rb, line 568
def notify(event, tuple, sec=nil)
  template = NotifyTemplateEntry.new(self, event, tuple, sec)
  synchronize do
    @notify_waiter.push(template)
  end
  template
end
read(tuple, sec=nil) { |template| ... } click to toggle source

Reads tuple, but does not remove it.

# File lib/rinda/tuplespace.rb, line 522
def read(tuple, sec=nil)
  template = WaitTemplateEntry.new(self, tuple, sec)
  yield(template) if block_given?
  synchronize do
    entry = @bag.find(template)
    return entry.value if entry
    raise RequestExpiredError if template.expired?

    begin
      @read_waiter.push(template)
      start_keeper if template.expires
      template.wait
      raise RequestCanceledError if template.canceled?
      raise RequestExpiredError if template.expired?
      return template.found
    ensure
      @read_waiter.delete(template)
    end
  end
end
read_all(tuple) click to toggle source

Returns all tuples matching tuple. Does not remove the found tuples.

# File lib/rinda/tuplespace.rb, line 546
def read_all(tuple)
  template = WaitTemplateEntry.new(self, tuple, nil)
  synchronize do
    entry = @bag.find_all(template)
    entry.collect do |e|
      e.value
    end
  end
end
take(tuple, sec=nil, &block) click to toggle source

Removes tuple

# File lib/rinda/tuplespace.rb, line 478
def take(tuple, sec=nil, &block)
  move(nil, tuple, sec, &block)
end
write(tuple, sec=nil) click to toggle source

Adds tuple

# File lib/rinda/tuplespace.rb, line 451
def write(tuple, sec=nil)
  entry = create_entry(tuple, sec)
  synchronize do
    if entry.expired?
      @read_waiter.find_all_template(entry).each do |template|
        template.read(tuple)
      end
      notify_event('write', entry.value)
      notify_event('delete', entry.value)
    else
      @bag.push(entry)
      start_keeper if entry.expires
      @read_waiter.find_all_template(entry).each do |template|
        template.read(tuple)
      end
      @take_waiter.find_all_template(entry).each do |template|
        template.signal
      end
      notify_event('write', entry.value)
    end
  end
  entry
end


class Rinda::TupleSpaceProxy - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::TupleSpaceProxy

TupleSpaceProxy allows a remote Tuplespace to appear as local.

In Files

  • lib/rinda/rinda.rb

Parent

Object

Public Class Methods

new(ts) click to toggle source

Creates a new TupleSpaceProxy to wrap ts.

# File lib/rinda/rinda.rb, line 213
def initialize(ts)
  @ts = ts
end

Public Instance Methods

notify(ev, tuple, sec=nil) click to toggle source

Registers for notifications of event ev on the proxied TupleSpace. See Rinda::TupleSpace#notify

# File lib/rinda/rinda.rb, line 252
def notify(ev, tuple, sec=nil)
  @ts.notify(ev, tuple, sec)
end
read(tuple, sec=nil, &block) click to toggle source

Reads tuple from the proxied TupleSpace. See Rinda::TupleSpace#read.

# File lib/rinda/rinda.rb, line 236
def read(tuple, sec=nil, &block)
  @ts.read(tuple, sec, &block)
end
read_all(tuple) click to toggle source

Reads all tuples matching tuple from the proxied TupleSpace. See Rinda::TupleSpace#read_all.

# File lib/rinda/rinda.rb, line 244
def read_all(tuple)
  @ts.read_all(tuple)
end
take(tuple, sec=nil, &block) click to toggle source

Takes tuple from the proxied TupleSpace. See Rinda::TupleSpace#take.

# File lib/rinda/rinda.rb, line 227
def take(tuple, sec=nil, &block)
  port = []
  @ts.move(DRbObject.new(port), tuple, sec, &block)
  port[0]
end
write(tuple, sec=nil) click to toggle source

Adds tuple to the proxied TupleSpace. See Rinda::TupleSpace#write.

# File lib/rinda/rinda.rb, line 220
def write(tuple, sec=nil)
  @ts.write(tuple, sec)
end


class Rinda::WaitTemplateEntry - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Rinda::WaitTemplateEntry

Documentation?

In Files

  • lib/rinda/tuplespace.rb

Parent

Rinda::TemplateEntry

Attributes

found[R]

Public Class Methods

new(place, ary, expires=nil) click to toggle source
# File lib/rinda/tuplespace.rb, line 187
def initialize(place, ary, expires=nil)
  super(ary, expires)
  @place = place
  @cond = place.new_cond
  @found = nil
end

Public Instance Methods

cancel() click to toggle source
# File lib/rinda/tuplespace.rb, line 194
def cancel
  super
  signal
end
read(tuple) click to toggle source
# File lib/rinda/tuplespace.rb, line 203
def read(tuple)
  @found = tuple
  signal
end
signal() click to toggle source
# File lib/rinda/tuplespace.rb, line 208
def signal
  @place.synchronize do
    @cond.signal
  end
end
wait() click to toggle source
# File lib/rinda/tuplespace.rb, line 199
def wait
  @cond.wait
end


class Ripper - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Ripper

Ripper is a Ruby script parser.

You can get information from the parser with event-based style. Information such as abstract syntax trees or simple lexical analysis of the Ruby program.

Usage

Ripper provides an easy interface for parsing your program into a symbolic expression tree (or S-expression).

Understanding the output of the parser may come as a challenge, it's recommended you use PP to format the output for legibility.

require 'ripper'
require 'pp'

pp Ripper.sexp('def hello(world) "Hello, #{world}!"; end')
  #=> [:program,
       [[:def,
         [:@ident, "hello", [1, 4]],
         [:paren,
          [:params, [[:@ident, "world", [1, 10]]], nil, nil, nil, nil, nil, nil]],
         [:bodystmt,
          [[:string_literal,
            [:string_content,
             [:@tstring_content, "Hello, ", [1, 18]],
             [:string_embexpr, [[:var_ref, [:@ident, "world", [1, 27]]]]],
             [:@tstring_content, "!", [1, 33]]]]],
          nil,
          nil,
          nil]]]]

You can see in the example above, the expression starts with :program.

From here, a method definition at :def, followed by the method's identifier :@ident. After the method's identifier comes the parentheses :paren and the method parameters under :params.

Next is the method body, starting at :bodystmt (stmt meaning statement), which contains the full definition of the method.

In our case, we're simply returning a String, so next we have the :string_literal expression.

Within our :string_literal you'll notice two @tstring_content, this is the literal part for Hello, and !. Between the two @tstring_content statements is a :string_embexpr, where embexpr is an embedded expression. Our expression consists of a local variable, or var_ref, with the identifier (@ident) of world.

Resources

  • Ruby Inside

Requirements

  • ruby 1.9 (support CVS HEAD only)

  • bison 1.28 or later (Other yaccs do not work)

License

Ruby License.

                                              Minero Aoki
                                      aamine@loveruby.net
                                    http://i.loveruby.net

In Files

  • ext/ripper/lib/ripper/core.rb
  • ext/ripper/lib/ripper/filter.rb
  • ext/ripper/lib/ripper/lexer.rb
  • ext/ripper/lib/ripper/sexp.rb
  • ext/ripper/lib/ripper.rb
  • ext/ripper/ripper.c

Parent

Object

Constants

EVENTS

This array contains name of all ripper events.

PARSER_EVENTS

This array contains name of parser events.

SCANNER_EVENTS

This array contains name of scanner events.

Version

Public Class Methods

lex(src, filename = '-', lineno = 1) click to toggle source

Tokenizes the Ruby program and returns an array of an array, which is formatted like [[lineno, column], type, token].

require 'ripper'
require 'pp'

pp Ripper.lex("def m(a) nil end")
  #=> [[[1,  0], :on_kw,     "def"],
       [[1,  3], :on_sp,     " "  ],
       [[1,  4], :on_ident,  "m"  ],
       [[1,  5], :on_lparen, "("  ],
       [[1,  6], :on_ident,  "a"  ],
       [[1,  7], :on_rparen, ")"  ],
       [[1,  8], :on_sp,     " "  ],
       [[1,  9], :on_kw,     "nil"],
       [[1, 12], :on_sp,     " "  ],
       [[1, 13], :on_kw,     "end"]]

# File ext/ripper/lib/ripper/lexer.rb, line 42
def Ripper.lex(src, filename = '-', lineno = 1)
  Lexer.new(src, filename, lineno).lex
end
new(src, filename="(ripper)", lineno=1) → ripper click to toggle source

Create a new Ripper object. src must be a String, an IO, or an Object which has gets method.

This method does not starts parsing. See also #parse and ::parse.

static VALUE
ripper_initialize(int argc, VALUE *argv, VALUE self)
{
    struct parser_params *parser;
    VALUE src, fname, lineno;

    TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
    rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
    if (RB_TYPE_P(src, T_FILE)) {
        parser->parser_lex_gets = ripper_lex_get_generic;
    }
    else {
        StringValue(src);
        parser->parser_lex_gets = lex_get_str;
    }
    parser->parser_lex_input = src;
    parser->eofp = Qfalse;
    if (NIL_P(fname)) {
        fname = STR_NEW2("(ripper)");
    }
    else {
        StringValue(fname);
    }
    parser_initialize(parser);

    parser->parser_ruby_sourcefile_string = fname;
    parser->parser_ruby_sourcefile = RSTRING_PTR(fname);
    parser->parser_ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;

    return Qnil;
}
parse(src, filename = '(ripper)', lineno = 1) click to toggle source

Parses the given Ruby program read from src. src must be a String or an IO or a object with a gets method.

# File ext/ripper/lib/ripper/core.rb, line 17
def Ripper.parse(src, filename = '(ripper)', lineno = 1)
  new(src, filename, lineno).parse
end
sexp(src, filename = '-', lineno = 1) click to toggle source
EXPERIMENTAL

Parses src and create S-exp tree. Returns more readable tree rather than ::sexp_raw. This method is mainly for developer use.

require 'ripper'
require 'pp'

pp Ripper.sexp("def m(a) nil end")
  #=> [:program,
       [[:def,
        [:@ident, "m", [1, 4]],
        [:paren, [:params, [[:@ident, "a", [1, 6]]], nil, nil, nil, nil]],
        [:bodystmt, [[:var_ref, [:@kw, "nil", [1, 9]]]], nil, nil, nil]]]]

# File ext/ripper/lib/ripper/sexp.rb, line 30
def Ripper.sexp(src, filename = '-', lineno = 1)
  SexpBuilderPP.new(src, filename, lineno).parse
end
sexp_raw(src, filename = '-', lineno = 1) click to toggle source
EXPERIMENTAL

Parses src and create S-exp tree. This method is mainly for developer use.

require 'ripper'
require 'pp'

pp Ripper.sexp_raw("def m(a) nil end")
  #=> [:program,
       [:stmts_add,
        [:stmts_new],
        [:def,
         [:@ident, "m", [1, 4]],
         [:paren, [:params, [[:@ident, "a", [1, 6]]], nil, nil, nil]],
         [:bodystmt,
          [:stmts_add, [:stmts_new], [:var_ref, [:@kw, "nil", [1, 9]]]],
          nil,
          nil,
          nil]]]]

# File ext/ripper/lib/ripper/sexp.rb, line 54
def Ripper.sexp_raw(src, filename = '-', lineno = 1)
  SexpBuilder.new(src, filename, lineno).parse
end
slice(src, pattern, n = 0) click to toggle source
EXPERIMENTAL

Parses src and return a string which was matched to pattern. pattern should be described as Regexp.

require 'ripper'

p Ripper.slice('def m(a) nil end', 'ident')                   #=> "m"
p Ripper.slice('def m(a) nil end', '[ident lparen rparen]+')  #=> "m(a)"
p Ripper.slice("<<EOS\nstring\nEOS",
               'heredoc_beg nl $(tstring_content*) heredoc_end', 1)
    #=> "string\n"

# File ext/ripper/lib/ripper/lexer.rb, line 84
def Ripper.slice(src, pattern, n = 0)
  if m = token_match(src, pattern)
  then m.string(n)
  else nil
  end
end
tokenize(src, filename = '-', lineno = 1) click to toggle source

Tokenizes the Ruby program and returns an array of strings.

p Ripper.tokenize("def m(a) nil end")
   # => ["def", " ", "m", "(", "a", ")", " ", "nil", " ", "end"]

# File ext/ripper/lib/ripper/lexer.rb, line 20
def Ripper.tokenize(src, filename = '-', lineno = 1)
  Lexer.new(src, filename, lineno).tokenize
end

Public Instance Methods

ripper#column → Integer click to toggle source

Return column number of current parsing line. This number starts from 0.

static VALUE
ripper_column(VALUE self)
{
    struct parser_params *parser;
    long col;

    TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
    if (!ripper_initialized_p(parser)) {
        rb_raise(rb_eArgError, "method called for uninitialized object");
    }
    if (NIL_P(parser->parsing_thread)) return Qnil;
    col = parser->tokp - parser->parser_lex_pbeg;
    return LONG2NUM(col);
}
ripper#encoding → encoding click to toggle source

Return encoding of the source.

VALUE
rb_parser_encoding(VALUE vparser)
{
    struct parser_params *parser;

    TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
    return rb_enc_from_encoding(current_enc);
}
ripper#end_seen? → Boolean click to toggle source

Return true if parsed source ended by +__END__+.

VALUE
rb_parser_end_seen_p(VALUE vparser)
{
    struct parser_params *parser;

    TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
    return ruby__end__seen ? Qtrue : Qfalse;
}
ripper#filename → String click to toggle source

Return current parsing filename.

static VALUE
ripper_filename(VALUE self)
{
    struct parser_params *parser;

    TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
    if (!ripper_initialized_p(parser)) {
        rb_raise(rb_eArgError, "method called for uninitialized object");
    }
    return parser->parser_ruby_sourcefile_string;
}
ripper#lineno → Integer click to toggle source

Return line number of current parsing line. This number starts from 1.

static VALUE
ripper_lineno(VALUE self)
{
    struct parser_params *parser;

    TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
    if (!ripper_initialized_p(parser)) {
        rb_raise(rb_eArgError, "method called for uninitialized object");
    }
    if (NIL_P(parser->parsing_thread)) return Qnil;
    return INT2NUM(parser->parser_ruby_sourceline);
}
ripper#parse click to toggle source

Start parsing and returns the value of the root action.

static VALUE
ripper_parse(VALUE self)
{
    struct parser_params *parser;

    TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
    if (!ripper_initialized_p(parser)) {
        rb_raise(rb_eArgError, "method called for uninitialized object");
    }
    if (!NIL_P(parser->parsing_thread)) {
        if (parser->parsing_thread == rb_thread_current())
            rb_raise(rb_eArgError, "Ripper#parse is not reentrant");
        else
            rb_raise(rb_eArgError, "Ripper#parse is not multithread-safe");
    }
    parser->parsing_thread = rb_thread_current();
    rb_ensure(ripper_parse0, self, ripper_ensure, self);

    return parser->result;
}
yydebug → true or false click to toggle source

Get yydebug.

VALUE
rb_parser_get_yydebug(VALUE self)
{
    struct parser_params *parser;

    TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
    return yydebug ? Qtrue : Qfalse;
}
yydebug = flag click to toggle source

Set yydebug.

VALUE
rb_parser_set_yydebug(VALUE self, VALUE flag)
{
    struct parser_params *parser;

    TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
    yydebug = RTEST(flag);
    return flag;
}


class Ripper::Filter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Ripper::Filter

This class handles only scanner events, which are dispatched in the 'right' order (same with input).

In Files

  • ext/ripper/lib/ripper/filter.rb

Parent

Object

Public Class Methods

new(src, filename = '-', lineno = 1) click to toggle source

Creates a new Ripper::Filter instance, passes parameters src, filename, and lineno to Ripper::Lexer.new

The lexer is for internal use only.

# File ext/ripper/lib/ripper/filter.rb, line 23
def initialize(src, filename = '-', lineno = 1)
  @__lexer = Lexer.new(src, filename, lineno)
  @__line = nil
  @__col = nil
end

Public Instance Methods

column() click to toggle source

The column number of the current token. This value starts from 0. This method is valid only in event handlers.

# File ext/ripper/lib/ripper/filter.rb, line 44
def column
  @__col
end
filename() click to toggle source

The file name of the input.

# File ext/ripper/lib/ripper/filter.rb, line 30
def filename
  @__lexer.filename
end
lineno() click to toggle source

The line number of the current token. This value starts from 1. This method is valid only in event handlers.

# File ext/ripper/lib/ripper/filter.rb, line 37
def lineno
  @__line
end
parse(init = nil) click to toggle source

Starts the parser. init is a data accumulator and is passed to the next event handler (as of Enumerable#inject).

# File ext/ripper/lib/ripper/filter.rb, line 51
def parse(init = nil)
  data = init
  @__lexer.lex.each do |pos, event, tok|
    @__line, @__col = *pos
    data = if respond_to?(event, true)
           then __send__(event, tok, data)
           else on_default(event, tok, data)
           end
  end
  data
end


class RubyLex - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RubyLex

In Files

  • lib/irb/ruby-lex.rb

Parent

Object


module RubyToken - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module RubyToken

In Files

  • lib/irb/ruby-token.rb


class RubyToken::TkError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RubyToken::TkError

In Files

  • lib/irb/ruby-token.rb

Parent

RubyToken::Token


class RubyToken::TkId - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RubyToken::TkId

In Files

  • lib/irb/ruby-token.rb

Parent

RubyToken::Token


class RubyToken::TkNode - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RubyToken::TkNode

In Files

  • lib/irb/ruby-token.rb

Parent

RubyToken::Token


class RubyToken::TkOPASGN - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RubyToken::TkOPASGN

In Files

  • lib/irb/ruby-token.rb

Parent

RubyToken::TkOp


class RubyToken::TkOp - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RubyToken::TkOp

In Files

  • lib/irb/ruby-token.rb

Parent

RubyToken::Token


class RubyToken::TkUnknownChar - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RubyToken::TkUnknownChar

In Files

  • lib/irb/ruby-token.rb

Parent

RubyToken::Token


class RubyToken::TkVal - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RubyToken::TkVal

In Files

  • lib/irb/ruby-token.rb

Parent

RubyToken::Token


class RubyToken::Token - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class RubyToken::Token

In Files

  • lib/irb/ruby-token.rb

Parent

Object


class SDBM - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class SDBM

SDBM provides a simple file-based key-value store, which can only store String keys and values.

Note that Ruby comes with the source code for SDBM, while the DBM and GDBM standard libraries rely on external libraries and headers.

Examples

Insert values:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db['apple'] = 'fruit'
  db['pear'] = 'fruit'
  db['carrot'] = 'vegetable'
  db['tomato'] = 'vegetable'
end

Bulk update:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db.update('peach' => 'fruit', 'tomato' => 'fruit')
end

Retrieve values:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db.each do |key, value|
    puts "Key: #{key}, Value: #{value}"
  end
end

Outputs:

Key: apple, Value: fruit
Key: pear, Value: fruit
Key: carrot, Value: vegetable
Key: peach, Value: fruit
Key: tomato, Value: fruit

In Files

  • ext/sdbm/init.c

Parent

Object

Included Modules

  • Enumerable

Public Class Methods

new(filename, mode = 0666) click to toggle source

Creates a new database handle by opening the given filename. SDBM actually uses two physical files, with extensions '.dir' and '.pag'. These extensions will automatically be appended to the filename.

If the file does not exist, a new file will be created using the given mode, unless mode is explicitly set to nil. In the latter case, no database will be created.

If the file exists, it will be opened in read/write mode. If this fails, it will be opened in read-only mode.

static VALUE
fsdbm_initialize(int argc, VALUE *argv, VALUE obj)
{
    volatile VALUE file;
    VALUE vmode;
    DBM *dbm;
    struct dbmdata *dbmp;
    int mode;

    if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
        mode = 0666;           /* default value */
    }
    else if (NIL_P(vmode)) {
        mode = -1;             /* return nil if DB not exist */
    }
    else {
        mode = NUM2INT(vmode);
    }
    FilePathValue(file);

    dbm = 0;
    if (mode >= 0)
        dbm = sdbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT, mode);
    if (!dbm)
        dbm = sdbm_open(RSTRING_PTR(file), O_RDWR, 0);
    if (!dbm)
        dbm = sdbm_open(RSTRING_PTR(file), O_RDONLY, 0);

    if (!dbm) {
        if (mode == -1) return Qnil;
        rb_sys_fail_str(file);
    }

    dbmp = ALLOC(struct dbmdata);
    DATA_PTR(obj) = dbmp;
    dbmp->di_dbm = dbm;
    dbmp->di_size = -1;

    return obj;
}
open(filename, mode = 0666) click to toggle source
open(filename, mode = 0666) { |sdbm| ... }

If called without a block, this is the same as ::new.

If a block is given, the new database will be passed to the block and will be safely closed after the block has executed.

Example:

require 'sdbm'

SDBM.open('my_database') do |db|
  db['hello'] = 'world'
end

static VALUE
fsdbm_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE obj = Data_Wrap_Struct(klass, 0, free_sdbm, 0);

    if (NIL_P(fsdbm_initialize(argc, argv, obj))) {
        return Qnil;
    }

    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, obj, fsdbm_close, obj);
    }

    return obj;
}

Public Instance Methods

sdbm[key] → value or nil click to toggle source

Returns the value in the database associated with the given key string.

If no value is found, returns nil.

static VALUE
fsdbm_aref(VALUE obj, VALUE keystr)
{
    return fsdbm_fetch(obj, keystr, Qnil);
}
sdbm[key] = value → value click to toggle source
store(key, value) → value

Stores a new value in the database with the given key as an index.

If the key already exists, this will update the value associated with the key.

Returns the given value.

static VALUE
fsdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    if (valstr == Qnil) {
        fsdbm_delete(obj, keystr);
        return Qnil;
    }

    fdbm_modify(obj);
    ExportStringValue(keystr);
    ExportStringValue(valstr);

    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LENINT(keystr);

    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LENINT(valstr);

    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;
    if (sdbm_store(dbm, key, val, DBM_REPLACE)) {
#ifdef HAVE_DBM_CLAERERR
        sdbm_clearerr(dbm);
#endif
        if (errno == EPERM) rb_sys_fail(0);
        rb_raise(rb_eDBMError, "sdbm_store failed");
    }

    return valstr;
}
clear → self click to toggle source

Deletes all data from the database.

static VALUE
fsdbm_clear(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;
    while (key = sdbm_firstkey(dbm), key.dptr) {
        if (sdbm_delete(dbm, key)) {
            rb_raise(rb_eDBMError, "sdbm_delete failed");
        }
    }
    dbmp->di_size = 0;

    return obj;
}
close → nil click to toggle source

Closes the database file.

Raises SDBMError if the database is already closed.

static VALUE
fsdbm_close(VALUE obj)
{
    struct dbmdata *dbmp;

    GetDBM(obj, dbmp);
    sdbm_close(dbmp->di_dbm);
    dbmp->di_dbm = 0;

    return Qnil;
}
closed? → true or false click to toggle source

Returns true if the database is closed.

static VALUE
fsdbm_closed(VALUE obj)
{
    struct dbmdata *dbmp;

    Data_Get_Struct(obj, struct dbmdata, dbmp);
    if (dbmp == 0)
        return Qtrue;
    if (dbmp->di_dbm == 0)
        return Qtrue;

    return Qfalse;
}
delete(key) → value or nil click to toggle source
delete(key) { |key, value| ... }

Deletes the key-value pair corresponding to the given key. If the key exists, the deleted value will be returned, otherwise nil.

If a block is provided, the deleted key and value will be passed to the block as arguments. If the key does not exist in the database, the value will be nil.

static VALUE
fsdbm_delete(VALUE obj, VALUE keystr)
{
    datum key, value;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE valstr;

    fdbm_modify(obj);
    ExportStringValue(keystr);
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LENINT(keystr);

    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;

    value = sdbm_fetch(dbm, key);
    if (value.dptr == 0) {
        if (rb_block_given_p()) return rb_yield(keystr);
        return Qnil;
    }

    /* need to save value before sdbm_delete() */
    valstr = rb_external_str_new(value.dptr, value.dsize);

    if (sdbm_delete(dbm, key)) {
        dbmp->di_size = -1;
        rb_raise(rb_eDBMError, "dbm_delete failed");
    }
    else if (dbmp->di_size >= 0) {
        dbmp->di_size--;
    }
    return valstr;
}
delete_if { |key, value| ... } → self click to toggle source
reject! { |key, value| ... } → self

Iterates over the key-value pairs in the database, deleting those for which the block returns true.

static VALUE
fsdbm_delete_if(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_new();
    int i, status = 0, n;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    n = dbmp->di_size;
    dbmp->di_size = -1;
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        keystr = rb_external_str_new(key.dptr, key.dsize);
        valstr = rb_external_str_new(val.dptr, val.dsize);
        ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
        if (status != 0) break;
        if (RTEST(ret)) rb_ary_push(ary, keystr);
        GetDBM2(obj, dbmp, dbm);
    }

    for (i = 0; i < RARRAY_LEN(ary); i++) {
        keystr = RARRAY_PTR(ary)[i];
        ExportStringValue(keystr);
        key.dptr = RSTRING_PTR(keystr);
        key.dsize = RSTRING_LENINT(keystr);
        if (sdbm_delete(dbm, key)) {
            rb_raise(rb_eDBMError, "sdbm_delete failed");
        }
    }
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - RARRAY_LENINT(ary);

    return obj;
}
each click to toggle source
each { |key, value| ... }
each_pair
each_pair { |key, value| ... }

Iterates over each key-value pair in the database.

If no block is given, returns an Enumerator.

static VALUE
fsdbm_each_pair(VALUE obj)
{
    datum key, val;
    DBM *dbm;
    struct dbmdata *dbmp;
    VALUE keystr, valstr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        keystr = rb_external_str_new(key.dptr, key.dsize);
        valstr = rb_external_str_new(val.dptr, val.dsize);
        rb_yield(rb_assoc_new(keystr, valstr));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}
each_key click to toggle source
each_key { |key| ... }

Iterates over each key in the database.

If no block is given, returns an Enumerator.

static VALUE
fsdbm_each_key(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        rb_yield(rb_external_str_new(key.dptr, key.dsize));
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}
each click to toggle source
each { |key, value| ... }
each_pair
each_pair { |key, value| ... }

Iterates over each key-value pair in the database.

If no block is given, returns an Enumerator.

static VALUE
fsdbm_each_pair(VALUE obj)
{
    datum key, val;
    DBM *dbm;
    struct dbmdata *dbmp;
    VALUE keystr, valstr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        keystr = rb_external_str_new(key.dptr, key.dsize);
        valstr = rb_external_str_new(val.dptr, val.dsize);
        rb_yield(rb_assoc_new(keystr, valstr));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}
each_value click to toggle source
each_value { |value| ... }

Iterates over each value in the database.

If no block is given, returns an Enumerator.

static VALUE
fsdbm_each_value(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        rb_yield(rb_external_str_new(val.dptr, val.dsize));
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}
empty? → true or false click to toggle source

Returns true if the database is empty.

static VALUE
fsdbm_empty_p(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;

    GetDBM(obj, dbmp);
    if (dbmp->di_size < 0) {
        dbm = dbmp->di_dbm;

        for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
            return Qfalse;
        }
    }
    else {
        if (dbmp->di_size)
            return Qfalse;
    }
    return Qtrue;
}
fetch(key) → value or nil click to toggle source
fetch(key) { |key| ... }

Returns the value in the database associated with the given key string.

If a block is provided, the block will be called when there is no value associated with the given key. The key will be passed in as an argument to the block.

If no block is provided and no value is associated with the given key, then an IndexError will be raised.

static VALUE
fsdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
{
    VALUE keystr, valstr, ifnone;

    rb_scan_args(argc, argv, "11", &keystr, &ifnone);
    valstr = fsdbm_fetch(obj, keystr, ifnone);
    if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
        rb_raise(rb_eIndexError, "key not found");

    return valstr;
}
include?(key) → true or false click to toggle source
key?(key) → true or false
member?(key) → true or false
has_key?(key) → true or false

Returns true if the database contains the given key.

static VALUE
fsdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(keystr);
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LENINT(keystr);

    GetDBM2(obj, dbmp, dbm);
    val = sdbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
value?(key) → true or false click to toggle source
has_value?(key) → true or false

Returns true if the database contains the given value.

static VALUE
fsdbm_has_value(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(valstr);
    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LENINT(valstr);

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        if (val.dsize == RSTRING_LENINT(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
            return Qtrue;
    }
    return Qfalse;
}
include?(key) → true or false click to toggle source
key?(key) → true or false
member?(key) → true or false
has_key?(key) → true or false

Returns true if the database contains the given key.

static VALUE
fsdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(keystr);
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LENINT(keystr);

    GetDBM2(obj, dbmp, dbm);
    val = sdbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
invert → Hash click to toggle source

Returns a Hash in which the key-value pairs have been inverted.

Example:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db.update('apple' => 'fruit', 'spinach' => 'vegetable')

  db.invert  #=> {"fruit" => "apple", "vegetable" => "spinach"}
end

static VALUE
fsdbm_invert(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;
    VALUE hash = rb_hash_new();

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        keystr = rb_external_str_new(key.dptr, key.dsize);
        valstr = rb_external_str_new(val.dptr, val.dsize);
        rb_hash_aset(hash, valstr, keystr);
    }
    return hash;
}
key(value) → key click to toggle source

Returns the key associated with the given value. If more than one key corresponds to the given value, then the first key to be found will be returned. If no keys are found, nil will be returned.

static VALUE
fsdbm_key(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(valstr);
    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LENINT(valstr);

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        if (val.dsize == RSTRING_LEN(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
            return rb_external_str_new(key.dptr, key.dsize);
    }
    return Qnil;
}
include?(key) → true or false click to toggle source
key?(key) → true or false
member?(key) → true or false
has_key?(key) → true or false

Returns true if the database contains the given key.

static VALUE
fsdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(keystr);
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LENINT(keystr);

    GetDBM2(obj, dbmp, dbm);
    val = sdbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
keys → Array click to toggle source

Returns a new Array containing the keys in the database.

static VALUE
fsdbm_keys(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        rb_ary_push(ary, rb_external_str_new(key.dptr, key.dsize));
    }

    return ary;
}
length → integer click to toggle source
size → integer

Returns the number of keys in the database.

static VALUE
fsdbm_length(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;
    int i = 0;

    GetDBM2(obj, dbmp, dbm);
    if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);

    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}
include?(key) → true or false click to toggle source
key?(key) → true or false
member?(key) → true or false
has_key?(key) → true or false

Returns true if the database contains the given key.

static VALUE
fsdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(keystr);
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LENINT(keystr);

    GetDBM2(obj, dbmp, dbm);
    val = sdbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
reject { |key, value| ... } → Hash click to toggle source

Creates a new Hash using the key-value pairs from the database, then calls Hash#reject with the given block, which returns a Hash with only the key-value pairs for which the block returns false.

static VALUE
fsdbm_reject(VALUE obj)
{
    return rb_hash_delete_if(fsdbm_to_hash(obj));
}
delete_if { |key, value| ... } → self click to toggle source
reject! { |key, value| ... } → self

Iterates over the key-value pairs in the database, deleting those for which the block returns true.

static VALUE
fsdbm_delete_if(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_new();
    int i, status = 0, n;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    n = dbmp->di_size;
    dbmp->di_size = -1;
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        keystr = rb_external_str_new(key.dptr, key.dsize);
        valstr = rb_external_str_new(val.dptr, val.dsize);
        ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
        if (status != 0) break;
        if (RTEST(ret)) rb_ary_push(ary, keystr);
        GetDBM2(obj, dbmp, dbm);
    }

    for (i = 0; i < RARRAY_LEN(ary); i++) {
        keystr = RARRAY_PTR(ary)[i];
        ExportStringValue(keystr);
        key.dptr = RSTRING_PTR(keystr);
        key.dsize = RSTRING_LENINT(keystr);
        if (sdbm_delete(dbm, key)) {
            rb_raise(rb_eDBMError, "sdbm_delete failed");
        }
    }
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - RARRAY_LENINT(ary);

    return obj;
}
replace(pairs) → self click to toggle source

Empties the database, then inserts the given key-value pairs.

This method will work with any object which implements an #each_pair method, such as a Hash.

static VALUE
fsdbm_replace(VALUE obj, VALUE other)
{
    fsdbm_clear(obj);
    rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
    return obj;
}
select { |key, value| ... } → Array click to toggle source

Returns a new Array of key-value pairs for which the block returns true.

Example:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db['apple'] = 'fruit'
  db['pear'] = 'fruit'
  db['spinach'] = 'vegetable'

  veggies = db.select do |key, value|
    value == 'vegetable'
  end #=> [["apple", "fruit"], ["pear", "fruit"]]
end

static VALUE
fsdbm_select(VALUE obj)
{
    VALUE new = rb_ary_new();
    datum key, val;
    DBM *dbm;
    struct dbmdata *dbmp;

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        VALUE assoc, v;
        val = sdbm_fetch(dbm, key);
        assoc = rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
                             rb_external_str_new(val.dptr, val.dsize));
        v = rb_yield(assoc);
        if (RTEST(v)) {
            rb_ary_push(new, assoc);
        }
        GetDBM2(obj, dbmp, dbm);
    }

    return new;
}
shift → Array or nil click to toggle source

Removes a key-value pair from the database and returns them as an Array. If the database is empty, returns nil.

static VALUE
fsdbm_shift(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    key = sdbm_firstkey(dbm);
    if (!key.dptr) return Qnil;
    val = sdbm_fetch(dbm, key);
    keystr = rb_external_str_new(key.dptr, key.dsize);
    valstr = rb_external_str_new(val.dptr, val.dsize);
    sdbm_delete(dbm, key);
    if (dbmp->di_size >= 0) {
        dbmp->di_size--;
    }

    return rb_assoc_new(keystr, valstr);
}
length → integer click to toggle source
size → integer

Returns the number of keys in the database.

static VALUE
fsdbm_length(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;
    int i = 0;

    GetDBM2(obj, dbmp, dbm);
    if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);

    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}
sdbm[key] = value → value click to toggle source
store(key, value) → value

Stores a new value in the database with the given key as an index.

If the key already exists, this will update the value associated with the key.

Returns the given value.

static VALUE
fsdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    if (valstr == Qnil) {
        fsdbm_delete(obj, keystr);
        return Qnil;
    }

    fdbm_modify(obj);
    ExportStringValue(keystr);
    ExportStringValue(valstr);

    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LENINT(keystr);

    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LENINT(valstr);

    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;
    if (sdbm_store(dbm, key, val, DBM_REPLACE)) {
#ifdef HAVE_DBM_CLAERERR
        sdbm_clearerr(dbm);
#endif
        if (errno == EPERM) rb_sys_fail(0);
        rb_raise(rb_eDBMError, "sdbm_store failed");
    }

    return valstr;
}
to_a → Array click to toggle source

Returns a new Array containing each key-value pair in the database.

Example:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db.update('apple' => 'fruit', 'spinach' => 'vegetable')

  db.to_a  #=> [["apple", "fruit"], ["spinach", "vegetable"]]
end

static VALUE
fsdbm_to_a(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        rb_ary_push(ary, rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
                                      rb_external_str_new(val.dptr, val.dsize)));
    }

    return ary;
}
to_hash → Hash click to toggle source

Returns a new Hash containing each key-value pair in the database.

static VALUE
fsdbm_to_hash(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE hash;

    GetDBM2(obj, dbmp, dbm);
    hash = rb_hash_new();
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        rb_hash_aset(hash, rb_external_str_new(key.dptr, key.dsize),
                           rb_external_str_new(val.dptr, val.dsize));
    }

    return hash;
}
update(pairs) → self click to toggle source

Insert or update key-value pairs.

This method will work with any object which implements an #each_pair method, such as a Hash.

static VALUE
fsdbm_update(VALUE obj, VALUE other)
{
    rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
    return obj;
}
value?(key) → true or false click to toggle source
has_value?(key) → true or false

Returns true if the database contains the given value.

static VALUE
fsdbm_has_value(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(valstr);
    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LENINT(valstr);

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        if (val.dsize == RSTRING_LENINT(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
            return Qtrue;
    }
    return Qfalse;
}
values → Array click to toggle source

Returns a new Array containing the values in the database.

static VALUE
fsdbm_values(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        rb_ary_push(ary, rb_external_str_new(val.dptr, val.dsize));
    }

    return ary;
}
values_at(key, ...) → Array click to toggle source

Returns an Array of values corresponding to the given keys.

static VALUE
fsdbm_values_at(int argc, VALUE *argv, VALUE obj)
{
    VALUE new = rb_ary_new2(argc);
    int i;

    for (i=0; i<argc; i++) {
        rb_ary_push(new, fsdbm_fetch(obj, argv[i], Qnil));
    }

    return new;
}


class SDBMError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class SDBMError

Exception class used to return errors from the sdbm library.

In Files

  • ext/sdbm/init.c

Parent

StandardError


class SOCKSSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class SOCKSSocket

SOCKS is an Internet protocol that routes packets between a client and a server through a proxy server. SOCKS5, if supported, additionally provides authentication so only authorized users may access a server.

In Files

  • lib/resolv-replace.rb
  • ext/socket/sockssocket.c

Parent

TCPSocket

Public Class Methods

new(host, serv) click to toggle source
# File lib/resolv-replace.rb, line 71
def initialize(host, serv)
  original_resolv_initialize(IPSocket.getaddress(host), port)
end
new(host, serv) → socket click to toggle source

Opens a SOCKS connection to host via the SOCKS server serv.

static VALUE
socks_init(VALUE sock, VALUE host, VALUE serv)
{
    static int init = 0;

    if (init == 0) {
        SOCKSinit("ruby");
        init = 1;
    }

    return rsock_init_inetsock(sock, host, serv, Qnil, Qnil, INET_SOCKS);
}

Public Instance Methods

close() click to toggle source

Closes the SOCKS connection.

static VALUE
socks_s_close(VALUE sock)
{
    rb_io_t *fptr;

    if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
        rb_raise(rb_eSecurityError, "Insecure: can't close socket");
    }
    GetOpenFile(sock, fptr);
    shutdown(fptr->fd, 2);
    return rb_io_close(sock);
}


module Scanf - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Scanf

scanf for Ruby

Description

scanf is an implementation of the C function scanf(3), modified as necessary for ruby compatibility.

the methods provided are String#scanf, IO#scanf, and Kernel#scanf. Kernel#scanf is a wrapper around STDIN.scanf. IO#scanf can be used on any IO stream, including file handles and sockets. scanf can be called either with or without a block.

Scanf scans an input string or stream according to a format, as described below in Conversions, and returns an array of matches between the format and the input. The format is defined in a string, and is similar (though not identical) to the formats used in Kernel#printf and Kernel#sprintf.

The format may contain conversion specifiers, which tell scanf what form (type) each particular matched substring should be converted to (e.g., decimal integer, floating point number, literal string, etc.) The matches and conversions take place from left to right, and the conversions themselves are returned as an array.

The format string may also contain characters other than those in the conversion specifiers. White space (blanks, tabs, or newlines) in the format string matches any amount of white space, including none, in the input. Everything else matches only itself.

Scanning stops, and scanf returns, when any input character fails to match the specifications in the format string, or when input is exhausted, or when everything in the format string has been matched. All matches found up to the stopping point are returned in the return array (or yielded to the block, if a block was given).

Basic usage

require 'scanf'

# String#scanf and IO#scanf take a single argument, the format string
array = a_string.scanf("%d%s")
array = an_io.scanf("%d%s")

# Kernel#scanf reads from STDIN
array = scanf("%d%s")

Block usage

When called with a block, scanf keeps scanning the input, cycling back to the beginning of the format string, and yields a new array of conversions to the block every time the format string is matched (including partial matches, but not including complete failures). The actual return value of scanf when called with a block is an array containing the results of all the executions of the block.

str = "123 abc 456 def 789 ghi"
str.scanf("%d%s") { |num,str| [ num * 2, str.upcase ] }
# => [[246, "ABC"], [912, "DEF"], [1578, "GHI"]]

Conversions

The single argument to scanf is a format string, which generally includes one or more conversion specifiers. Conversion specifiers begin with the percent character ('%') and include information about what scanf should next scan for (string, decimal number, single character, etc.).

There may be an optional maximum field width, expressed as a decimal integer, between the % and the conversion. If no width is given, a default of `infinity' is used (with the exception of the %c specifier; see below). Otherwise, given a field width of n for a given conversion, at most n characters are scanned in processing that conversion. Before conversion begins, most conversions skip white space in the input string; this white space is not counted against the field width.

The following conversions are available.

%

Matches a literal `%'. That is, `%%' in the format string matches a single input `%' character. No conversion is done, and the resulting '%' is not included in the return array.

d

Matches an optionally signed decimal integer.

u

Same as d.

i

Matches an optionally signed integer. The integer is read in base 16 if it begins with `0x' or `0X', in base 8 if it begins with `0', and in base 10 other- wise. Only characters that correspond to the base are recognized.

o

Matches an optionally signed octal integer.

x, X

Matches an optionally signed hexadecimal integer,

a, e, f, g, A, E, F, G

Matches an optionally signed floating-point number.

s

Matches a sequence of non-white-space character. The input string stops at white space or at the maximum field width, whichever occurs first.

c

Matches a single character, or a sequence of n characters if a field width of n is specified. The usual skip of leading white space is suppressed. To skip white space first, use an explicit space in the format.

[

Matches a nonempty sequence of characters from the specified set of accepted characters. The usual skip of leading white space is suppressed. This bracketed sub-expression is interpreted exactly like a character class in a Ruby regular expression. (In fact, it is placed as-is in a regular expression.) The matching against the input string ends with the appearance of a character not in (or, with a circumflex, in) the set, or when the field width runs out, whichever comes first.

Assignment suppression

To require that a particular match occur, but without including the result in the return array, place the assignment suppression flag, which is the star character ('*'), immediately after the leading '%' of a format specifier (just before the field width, if any).

scanf for Ruby compared with scanf in C

scanf for Ruby is based on the C function scanf(3), but with modifications, dictated mainly by the underlying differences between the languages.

Unimplemented flags and specifiers

  • The only flag implemented in scanf for Ruby is '*' (ignore upcoming conversion). Many of the flags available in C versions of scanf(3) have to do with the type of upcoming pointer arguments, and are meaningless in Ruby.

  • The n specifier (store number of characters consumed so far in next pointer) is not implemented.

  • The p specifier (match a pointer value) is not implemented.

Altered specifiers

o, u, x, X

In scanf for Ruby, all of these specifiers scan for an optionally signed integer, rather than for an unsigned integer like their C counterparts.

Return values

scanf for Ruby returns an array of successful conversions, whereas scanf(3) returns the number of conversions successfully completed. (See below for more details on scanf for Ruby's return values.)

Return values

Without a block, scanf returns an array containing all the conversions it has found. If none are found, scanf will return an empty array. An unsuccessful match is never ignored, but rather always signals the end of the scanning operation. If the first unsuccessful match takes place after one or more successful matches have already taken place, the returned array will contain the results of those successful matches.

With a block scanf returns a 'map'-like array of transformations from the block – that is, an array reflecting what the block did with each yielded result from the iterative scanf operation. (See “Block usage”, above.)

Current limitations and bugs

When using IO#scanf under Windows, make sure you open your files in binary mode:

File.open("filename", "rb")

so that scanf can keep track of characters correctly.

Support for character classes is reasonably complete (since it essentially piggy-backs on Ruby's regular expression handling of character classes), but users are advised that character class testing has not been exhaustive, and that they should exercise some caution in using any of the more complex and/or arcane character class idioms.

License and copyright

Copyright

© 2002-2003 David Alan Black

License

Distributed on the same licensing terms as Ruby itself

Warranty disclaimer

This software is provided “as is” and without any express or implied warranties, including, without limitation, the implied warranties of merchantability and fitness for a particular purpose.

Credits and acknowledgements

scanf was developed as the major activity of the Austin Ruby Codefest (Austin, Texas, August 2002).

Principal author

David Alan Black (dblack@superlink.net)

Co-author

Hal Fulton (hal9000@hypermetrics.com)

Project contributors

Nolan Darilek, Jason Johnston

Thanks to Hal Fulton for hosting the Codefest.

Thanks to Matz for suggestions about the class design.

Thanks to Gavin Sinclair for some feedback on the documentation.

The text for parts of this document, especially the Description and Conversions sections, above, were adapted from the Linux Programmer's Manual manpage for scanf(3), dated 1995-11-01.

Bugs and bug reports

scanf for Ruby is based on something of an amalgam of C scanf implementations and documentation, rather than on a single canonical description. Suggestions for features and behaviors which appear in other scanfs, and would be meaningful in Ruby, are welcome, as are reports of suspicious behaviors and/or bugs. (Please see “Credits and acknowledgements”, above, for email addresses.)

In Files

  • lib/scanf.rb


class Scanf::FormatSpecifier - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Scanf::FormatSpecifier

In Files

  • lib/scanf.rb

Parent

Object


class Scanf::FormatString - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Scanf::FormatString

In Files

  • lib/scanf.rb

Parent

Object


module SecureRandom - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module SecureRandom

In Files

  • lib/securerandom.rb

Public Class Methods

base64(n=nil) click to toggle source

::base64 generates a random base64 string.

The argument n specifies the length of the random length. The length of the result string is about 4/3 of n.

If n is not specified, 16 is assumed. It may be larger in future.

The result may contain A-Z, a-z, 0-9, “+”, “/” and “=”.

p SecureRandom.base64 #=> "/2BuBuLf3+WfSKyQbRcc/A=="
p SecureRandom.base64 #=> "6BbW0pxO0YENxn38HMUbcQ=="

If secure random number generator is not available, NotImplementedError is raised.

See RFC 3548 for the definition of base64.

# File lib/securerandom.rb, line 161
def self.base64(n=nil)
  [random_bytes(n)].pack("m*").delete("\n")
end
hex(n=nil) click to toggle source

::hex generates a random hex string.

The argument n specifies the length of the random length. The length of the result string is twice of n.

If n is not specified, 16 is assumed. It may be larger in future.

The result may contain 0-9 and a-f.

p SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"
p SecureRandom.hex #=> "91dc3bfb4de5b11d029d376634589b61"

If secure random number generator is not available, NotImplementedError is raised.

# File lib/securerandom.rb, line 140
def self.hex(n=nil)
  random_bytes(n).unpack("H*")[0]
end
random_bytes(n=nil) click to toggle source

::random_bytes generates a random binary string.

The argument n specifies the length of the result string.

If n is not specified, 16 is assumed. It may be larger in future.

The result may contain any byte: “x00” - “xff”.

p SecureRandom.random_bytes #=> "\xD8\\\xE0\xF4\r\xB2\xFC*WM\xFF\x83\x18\xF45\xB6"
p SecureRandom.random_bytes #=> "m\xDC\xFC/\a\x00Uf\xB2\xB2P\xBD\xFF6S\x97"

If secure random number generator is not available, NotImplementedError is raised.

# File lib/securerandom.rb, line 56
def self.random_bytes(n=nil)
  n = n ? n.to_int : 16

  if defined? OpenSSL::Random
    @pid = 0 if !defined?(@pid)
    pid = $$
    if @pid != pid
      now = Time.now
      ary = [now.to_i, now.nsec, @pid, pid]
      OpenSSL::Random.seed(ary.to_s)
      @pid = pid
    end
    return OpenSSL::Random.random_bytes(n)
  end

  if !defined?(@has_urandom) || @has_urandom
    flags = File::RDONLY
    flags |= File::NONBLOCK if defined? File::NONBLOCK
    flags |= File::NOCTTY if defined? File::NOCTTY
    begin
      File.open("/dev/urandom", flags) {|f|
        unless f.stat.chardev?
          raise Errno::ENOENT
        end
        @has_urandom = true
        ret = f.read(n)
        if ret.length != n
          raise NotImplementedError, "Unexpected partial read from random device: only #{ret.length} for #{n} bytes"
        end
        return ret
      }
    rescue Errno::ENOENT
      @has_urandom = false
    end
  end

  if !defined?(@has_win32)
    begin
      require 'Win32API'

      crypt_acquire_context = Win32API.new("advapi32", "CryptAcquireContext", 'PPPII', 'L')
      @crypt_gen_random = Win32API.new("advapi32", "CryptGenRandom", 'VIP', 'L')

      hProvStr = " " * DL::SIZEOF_VOIDP
      prov_rsa_full = 1
      crypt_verifycontext = 0xF0000000

      if crypt_acquire_context.call(hProvStr, nil, nil, prov_rsa_full, crypt_verifycontext) == 0
        raise SystemCallError, "CryptAcquireContext failed: #{lastWin32ErrorMessage}"
      end
      type = DL::SIZEOF_VOIDP == DL::SIZEOF_LONG_LONG ? 'q' : 'l'
      @hProv, = hProvStr.unpack(type)

      @has_win32 = true
    rescue LoadError
      @has_win32 = false
    end
  end
  if @has_win32
    bytes = " ".force_encoding("ASCII-8BIT") * n
    if @crypt_gen_random.call(@hProv, bytes.size, bytes) == 0
      raise SystemCallError, "CryptGenRandom failed: #{lastWin32ErrorMessage}"
    end
    return bytes
  end

  raise NotImplementedError, "No random device"
end
random_number(n=0) click to toggle source

::random_number generates a random number.

If a positive integer is given as n, ::random_number returns an integer: 0 <= ::random_number < n.

p SecureRandom.random_number(100) #=> 15
p SecureRandom.random_number(100) #=> 88

If 0 is given or an argument is not given, ::random_number returns a float: 0.0 <= ::random_number < 1.0.

p SecureRandom.random_number #=> 0.596506046187744
p SecureRandom.random_number #=> 0.350621695741409

# File lib/securerandom.rb, line 215
def self.random_number(n=0)
  if 0 < n
    hex = n.to_s(16)
    hex = '0' + hex if (hex.length & 1) == 1
    bin = [hex].pack("H*")
    mask = bin[0].ord
    mask |= mask >> 1
    mask |= mask >> 2
    mask |= mask >> 4
    begin
      rnd = SecureRandom.random_bytes(bin.length)
      rnd[0] = (rnd[0].ord & mask).chr
    end until rnd < bin
    rnd.unpack("H*")[0].hex
  else
    # assumption: Float::MANT_DIG <= 64
    i64 = SecureRandom.random_bytes(8).unpack("Q")[0]
    Math.ldexp(i64 >> (64-Float::MANT_DIG), -Float::MANT_DIG)
  end
end
urlsafe_base64(n=nil, padding=false) click to toggle source

::urlsafe_base64 generates a random URL-safe base64 string.

The argument n specifies the length of the random length. The length of the result string is about 4/3 of n.

If n is not specified, 16 is assumed. It may be larger in future.

The boolean argument padding specifies the padding. If it is false or nil, padding is not generated. Otherwise padding is generated. By default, padding is not generated because “=” may be used as a URL delimiter.

The result may contain A-Z, a-z, 0-9, “-” and “_”. “=” is also used if padding is true.

p SecureRandom.urlsafe_base64 #=> "b4GOKm4pOYU_-BOXcrUGDg"
p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"

p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
p SecureRandom.urlsafe_base64(nil, true) #=> "-M8rLhr7JEpJlqFGUMmOxg=="

If secure random number generator is not available, NotImplementedError is raised.

See RFC 3548 for the definition of URL-safe base64.

# File lib/securerandom.rb, line 191
def self.urlsafe_base64(n=nil, padding=false)
  s = [random_bytes(n)].pack("m*")
  s.delete!("\n")
  s.tr!("+/", "-_")
  s.delete!("=") if !padding
  s
end
uuid() click to toggle source

::uuid generates a v4 random UUID (Universally Unique IDentifier).

p SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
p SecureRandom.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
p SecureRandom.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"

The version 4 UUID is purely random (except the version). It doesn't contain meaningful information such as MAC address, time, etc.

See RFC 4122 for details of UUID.

# File lib/securerandom.rb, line 247
def self.uuid
  ary = self.random_bytes(16).unpack("NnnnnN")
  ary[2] = (ary[2] & 0x0fff) | 0x4000
  ary[3] = (ary[3] & 0x3fff) | 0x8000
  "%08x-%04x-%04x-%04x-%04x%08x" % ary
end


class Set - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Set

Set implements a collection of unordered values with no duplicates. This is a hybrid of Array's intuitive inter-operation facilities and Hash's fast lookup.

The equality of each couple of elements is determined according to Object#eql? and Object#hash, since Set uses Hash as storage.

Set is easy to use with Enumerable objects (implementing each). Most of the initializer methods and binary operators accept generic Enumerable objects besides sets and arrays. An Enumerable object can be converted to Set using the to_set method.

Comparison

The comparison operators <, >, <= and >= are implemented as shorthand for the {proper_,}{subset?,superset?} methods. However, the <=> operator is intentionally left out because not every pair of sets is comparable. ({x,y} vs. {x,z} for example)

Example

require 'set'
s1 = Set.new [1, 2]                   # -> #<Set: {1, 2}>
s2 = [1, 2].to_set                    # -> #<Set: {1, 2}>
s1 == s2                              # -> true
s1.add("foo")                         # -> #<Set: {1, 2, "foo"}>
s1.merge([2, 6])                      # -> #<Set: {6, 1, 2, "foo"}>
s1.subset? s2                         # -> false
s2.subset? s1                         # -> true

Contact

- Akinori MUSHA <knu@iDaemons.org> (current maintainer)

In Files

  • lib/set.rb

Parent

Object

Included Modules

  • Enumerable

Public Class Methods

[](*ary) click to toggle source

Creates a new set containing the given objects.

# File lib/set.rb, line 64
def self.[](*ary)
  new(ary)
end
new(enum = nil) { |o| ... } click to toggle source

Creates a new set containing the elements of the given enumerable object.

If a block is given, the elements of enum are preprocessed by the given block.

# File lib/set.rb, line 73
def initialize(enum = nil, &block) # :yields: o
  @hash ||= Hash.new

  enum.nil? and return

  if block
    do_with_enum(enum) { |o| add(block[o]) }
  else
    merge(enum)
  end
end

Public Instance Methods

&(enum) click to toggle source

Returns a new set containing elements common to the set and the given enumerable object.

# File lib/set.rb, line 350
def &(enum)
  n = self.class.new
  do_with_enum(enum) { |o| n.add(o) if include?(o) }
  n
end
Also aliased as: intersection
+(enum) click to toggle source
Alias for: |
-(enum) click to toggle source

Returns a new set built by duplicating the set, removing every element that appears in the given enumerable object.

# File lib/set.rb, line 343
def -(enum)
  dup.subtract(enum)
end
Also aliased as: difference
<(set) click to toggle source
Alias for: proper_subset?
<<(o) click to toggle source
Alias for: add
<=(set) click to toggle source
Alias for: subset?
==(other) click to toggle source

Returns true if two sets are equal. The equality of each couple of elements is defined according to Object#eql?.

# File lib/set.rb, line 368
def ==(other)
  if self.equal?(other)
    true
  elsif other.instance_of?(self.class)
    @hash == other.instance_variable_get(:@hash)
  elsif other.is_a?(Set) && self.size == other.size
    other.all? { |o| @hash.include?(o) }
  else
    false
  end
end
>(set) click to toggle source
Alias for: proper_superset?
>=(set) click to toggle source
Alias for: superset?
^(enum) click to toggle source

Returns a new set containing elements exclusive between the set and the given enumerable object. (set ^ enum) is equivalent to ((set | enum) - (set & enum)).

# File lib/set.rb, line 360
def ^(enum)
  n = Set.new(enum)
  each { |o| if n.include?(o) then n.delete(o) else n.add(o) end }
  n
end
add(o) click to toggle source

Adds the given object to the set and returns self. Use merge to add many elements at once.

# File lib/set.rb, line 238
def add(o)
  @hash[o] = true
  self
end
Also aliased as: <<
add?(o) click to toggle source

Adds the given object to the set and returns self. If the object is already in the set, returns nil.

# File lib/set.rb, line 246
def add?(o)
  if include?(o)
    nil
  else
    add(o)
  end
end
classify() { |o| ... } click to toggle source

Classifies the set by the return value of the given block and returns a hash of {value => set of elements} pairs. The block is called once for each element of the set, passing the element as parameter.

e.g.:

require 'set'
files = Set.new(Dir.glob("*.rb"))
hash = files.classify { |f| File.mtime(f).year }
p hash    # => {2000=>#<Set: {"a.rb", "b.rb"}>,
          #     2001=>#<Set: {"c.rb", "d.rb", "e.rb"}>,
          #     2002=>#<Set: {"f.rb"}>}

# File lib/set.rb, line 402
def classify # :yields: o
  block_given? or return enum_for(__method__)

  h = {}

  each { |i|
    x = yield(i)
    (h[x] ||= self.class.new).add(i)
  }

  h
end
clear() click to toggle source

Removes all elements and returns self.

# File lib/set.rb, line 131
def clear
  @hash.clear
  self
end
collect!() { |o| ... } click to toggle source

Replaces the elements with ones returned by collect().

# File lib/set.rb, line 288
def collect!
  block_given? or return enum_for(__method__)
  set = self.class.new
  each { |o| set << yield(o) }
  replace(set)
end
Also aliased as: map!
delete(o) click to toggle source

Deletes the given object from the set and returns self. Use subtract to delete many items at once.

# File lib/set.rb, line 256
def delete(o)
  @hash.delete(o)
  self
end
delete?(o) click to toggle source

Deletes the given object from the set and returns self. If the object is not in the set, returns nil.

# File lib/set.rb, line 263
def delete?(o)
  if include?(o)
    delete(o)
  else
    nil
  end
end
delete_if() { |o| ... } click to toggle source

Deletes every element of the set for which block evaluates to true, and returns self.

# File lib/set.rb, line 273
def delete_if
  block_given? or return enum_for(__method__)
  to_a.each { |o| @hash.delete(o) if yield(o) }
  self
end
difference(enum) click to toggle source
Alias for: -
divide(&func) click to toggle source

Divides the set into a set of subsets according to the commonality defined by the given block.

If the arity of the block is 2, elements o1 and o2 are in common if block.call(o1, o2) is true. Otherwise, elements o1 and o2 are in common if block.call(o1) == block.call(o2).

e.g.:

require 'set'
numbers = Set[1, 3, 4, 6, 9, 10, 11]
set = numbers.divide { |i,j| (i - j).abs == 1 }
p set     # => #<Set: {#<Set: {1}>,
          #            #<Set: {11, 9, 10}>,
          #            #<Set: {3, 4}>,
          #            #<Set: {6}>}>

# File lib/set.rb, line 431
def divide(&func)
  func or return enum_for(__method__)

  if func.arity == 2
    require 'tsort'

    class << dig = {}         # :nodoc:
      include TSort

      alias tsort_each_node each_key
      def tsort_each_child(node, &block)
        fetch(node).each(&block)
      end
    end

    each { |u|
      dig[u] = a = []
      each{ |v| func.call(u, v) and a << v }
    }

    set = Set.new()
    dig.each_strongly_connected_component { |css|
      set.add(self.class.new(css))
    }
    set
  else
    Set.new(classify(&func).values)
  end
end
each(&block) click to toggle source

Calls the given block once for each element in the set, passing the element as parameter. Returns an enumerator if no block is given.

# File lib/set.rb, line 230
def each(&block)
  block or return enum_for(__method__)
  @hash.each_key(&block)
  self
end
empty?() click to toggle source

Returns true if the set contains no elements.

# File lib/set.rb, line 126
def empty?
  @hash.empty?
end
flatten() click to toggle source

Returns a new set that is a copy of the set, flattening each containing set recursively.

# File lib/set.rb, line 175
def flatten
  self.class.new.flatten_merge(self)
end
flatten!() click to toggle source

Equivalent to #flatten, but replaces the receiver with the result in place. Returns nil if no modifications were made.

# File lib/set.rb, line 181
def flatten!
  if detect { |e| e.is_a?(Set) }
    replace(flatten())
  else
    nil
  end
end
include?(o) click to toggle source

Returns true if the set contains the given object.

# File lib/set.rb, line 190
def include?(o)
  @hash.include?(o)
end
Also aliased as: member?
initialize_copy(orig) click to toggle source

Copy internal hash.

# File lib/set.rb, line 97
def initialize_copy(orig)
  @hash = orig.instance_variable_get(:@hash).dup
end
inspect() click to toggle source

Returns a string containing a human-readable representation of the set. (“#<Set: {element1, element2, …}>”)

# File lib/set.rb, line 465
def inspect
  ids = (Thread.current[InspectKey] ||= [])

  if ids.include?(object_id)
    return sprintf('#<%s: {...}>', self.class.name)
  end

  begin
    ids << object_id
    return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2])
  ensure
    ids.pop
  end
end
intersection(enum) click to toggle source
Alias for: &
keep_if() { |o| ... } click to toggle source

Deletes every element of the set for which block evaluates to false, and returns self.

# File lib/set.rb, line 281
def keep_if
  block_given? or return enum_for(__method__)
  to_a.each { |o| @hash.delete(o) unless yield(o) }
  self
end
length() click to toggle source
Alias for: size
map!() click to toggle source
Alias for: collect!
member?(o) click to toggle source
Alias for: include?
merge(enum) click to toggle source

Merges the elements of the given enumerable object to the set and returns self.

# File lib/set.rb, line 316
def merge(enum)
  if enum.instance_of?(self.class)
    @hash.update(enum.instance_variable_get(:@hash))
  else
    do_with_enum(enum) { |o| add(o) }
  end

  self
end
proper_subset?(set) click to toggle source

Returns true if the set is a proper subset of the given set.

# File lib/set.rb, line 220
def proper_subset?(set)
  set.is_a?(Set) or raise ArgumentError, "value must be a set"
  return false if set.size <= size
  all? { |o| set.include?(o) }
end
Also aliased as: <
proper_superset?(set) click to toggle source

Returns true if the set is a proper superset of the given set.

# File lib/set.rb, line 204
def proper_superset?(set)
  set.is_a?(Set) or raise ArgumentError, "value must be a set"
  return false if size <= set.size
  set.all? { |o| include?(o) }
end
Also aliased as: >
reject!(&block) click to toggle source

Equivalent to #delete_if, but returns nil if no changes were made.

# File lib/set.rb, line 298
def reject!(&block)
  block or return enum_for(__method__)
  n = size
  delete_if(&block)
  size == n ? nil : self
end
replace(enum) click to toggle source

Replaces the contents of the set with the contents of the given enumerable object and returns self.

# File lib/set.rb, line 138
def replace(enum)
  if enum.instance_of?(self.class)
    @hash.replace(enum.instance_variable_get(:@hash))
  else
    clear
    merge(enum)
  end

  self
end
select!(&block) click to toggle source

Equivalent to #keep_if, but returns nil if no changes were made.

# File lib/set.rb, line 307
def select!(&block)
  block or return enum_for(__method__)
  n = size
  keep_if(&block)
  size == n ? nil : self
end
size() click to toggle source

Returns the number of elements.

# File lib/set.rb, line 120
def size
  @hash.size
end
Also aliased as: length
subset?(set) click to toggle source

Returns true if the set is a subset of the given set.

# File lib/set.rb, line 212
def subset?(set)
  set.is_a?(Set) or raise ArgumentError, "value must be a set"
  return false if set.size < size
  all? { |o| set.include?(o) }
end
Also aliased as: <=
subtract(enum) click to toggle source

Deletes every element that appears in the given enumerable object and returns self.

# File lib/set.rb, line 328
def subtract(enum)
  do_with_enum(enum) { |o| delete(o) }
  self
end
superset?(set) click to toggle source

Returns true if the set is a superset of the given set.

# File lib/set.rb, line 196
def superset?(set)
  set.is_a?(Set) or raise ArgumentError, "value must be a set"
  return false if size < set.size
  set.all? { |o| include?(o) }
end
Also aliased as: >=
to_a() click to toggle source

Converts the set to an array. The order of elements is uncertain.

# File lib/set.rb, line 150
def to_a
  @hash.keys
end
union(enum) click to toggle source
Alias for: |
|(enum) click to toggle source

Returns a new set built by merging the set and the elements of the given enumerable object.

# File lib/set.rb, line 335
def |(enum)
  dup.merge(enum)
end
Also aliased as: +, union


class Shell - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell

Shell implements an idiomatic Ruby interface for common UNIX shell commands.

It provides users the ability to execute commands with filters and pipes, like sh/csh by using native facilities of Ruby.

Examples

Temp file creation

In this example we will create three tmpFile's in three different folders under the /tmp directory.

sh = Shell.cd("/tmp") # Change to the /tmp directory
sh.mkdir "shell-test-1" unless sh.exists?("shell-test-1")
# make the 'shell-test-1' directory if it doesn't already exist
sh.cd("shell-test-1") # Change to the /tmp/shell-test-1 directory
for dir in ["dir1", "dir3", "dir5"]
  if !sh.exists?(dir)
    sh.mkdir dir # make dir if it doesnt' already exist
    sh.cd(dir) do
      # change to the `dir` directory
      f = sh.open("tmpFile", "w") # open a new file in write mode
      f.print "TEST\n"            # write to the file
      f.close                     # close the file handler
    end
    print sh.pwd                  # output the process working directory
  end
end

Temp file creationg with self

This example is identical to the first, except we're using Shell::CommandProcessor#transact.

Shell::CommandProcessor#transact executes the given block against self, in this case sh; our Shell object. Within the block we can substitute sh.cd to cd, because the scope within the block uses sh already.

sh = Shell.cd("/tmp")
sh.transact do
  mkdir "shell-test-1" unless exists?("shell-test-1")
  cd("shell-test-1")
  for dir in ["dir1", "dir3", "dir5"]
    if !exists?(dir)
      mkdir dir
      cd(dir) do
        f = open("tmpFile", "w")
        f.print "TEST\n"
        f.close
      end
      print pwd
    end
  end
end

Pipe /etc/printcap into a file

In this example we will read the operating system file /etc/printcap, generated by cupsd, and then output it to a new file relative to the pwd of sh.

sh = Shell.new
sh.cat("/etc/printcap") | sh.tee("tee1") > "tee2"
(sh.cat < "/etc/printcap") | sh.tee("tee11") > "tee12"
sh.cat("/etc/printcap") | sh.tee("tee1") >> "tee2"
(sh.cat < "/etc/printcap") | sh.tee("tee11") >> "tee12"

In Files

  • lib/shell/builtin-command.rb
  • lib/shell/command-processor.rb
  • lib/shell/error.rb
  • lib/shell/filter.rb
  • lib/shell/process-controller.rb
  • lib/shell/system-command.rb
  • lib/shell/version.rb
  • lib/shell.rb

Parent

Object

Included Modules

  • Shell::Error

Attributes

cascade[RW]
debug[RW]
debug?[RW]
verbose[RW]
verbose?[RW]
command_processor[R]
cwd[R]

Returns the current working directory.

debug[RW]
debug?[RW]
dir[R]

Returns the current working directory.

dir_stack[R]
dirs[R]
getwd[R]

Returns the current working directory.

process_controller[R]
pwd[R]

Returns the current working directory.

record_separator[RW]
system_path[R]

Returns the command search path in an array

umask[RW]

Returns the umask

verbose[RW]
verbose?[RW]

Public Class Methods

alias_command(ali, command, *opts, &block) click to toggle source

Convenience method for Shell::CommandProcessor.alias_command

# File lib/shell.rb, line 369
def Shell.alias_command(ali, command, *opts, &block)
  CommandProcessor.alias_command(ali, command, *opts, &block)
end
cd(path) click to toggle source

Creates a new Shell instance with the current working directory set to path.

# File lib/shell.rb, line 127
def cd(path)
  new(path)
end
debug=(val) click to toggle source
# File lib/shell.rb, line 116
def debug=(val)
  @debug = val
  @verbose = val if val
end
def_system_command(command, path = command) click to toggle source

Convenience method for Shell::CommandProcessor.def_system_command

# File lib/shell.rb, line 359
def Shell.def_system_command(command, path = command)
  CommandProcessor.def_system_command(command, path)
end
default_record_separator() click to toggle source
# File lib/shell.rb, line 160
def default_record_separator
  if @default_record_separator
    @default_record_separator
  else
    $/
  end
end
default_record_separator=(rs) click to toggle source
# File lib/shell.rb, line 168
def default_record_separator=(rs)
  @default_record_separator = rs
end
default_system_path() click to toggle source

Returns the directories in the current shell's PATH environment variable as an array of directory names. This sets the #system_path for all instances of Shell.

Example: If in your current shell, you did:

$ echo $PATH
/usr/bin:/bin:/usr/local/bin

Running this method in the above shell would then return:

["/usr/bin", "/bin", "/usr/local/bin"]
# File lib/shell.rb, line 144
def default_system_path
  if @default_system_path
    @default_system_path
  else
    ENV["PATH"].split(":")
  end
end
default_system_path=(path) click to toggle source

Sets the #system_path that new instances of Shell should have as their initial system_path.

path should be an array of directory name strings.

# File lib/shell.rb, line 156
def default_system_path=(path)
  @default_system_path = path
end
install_system_commands(pre = "sys_") click to toggle source

Convenience method for Shell::CommandProcessor.install_system_commands

# File lib/shell.rb, line 379
def Shell.install_system_commands(pre = "sys_")
  CommandProcessor.install_system_commands(pre)
end
new(pwd, umask) → obj click to toggle source

Creates a Shell object which current directory is set to the process current directory, unless otherwise specified by the pwd argument.

# File lib/shell.rb, line 185
def initialize(pwd = Dir.pwd, umask = nil)
  @cwd = File.expand_path(pwd)
  @dir_stack = []
  @umask = umask

  @system_path = Shell.default_system_path
  @record_separator = Shell.default_record_separator

  @command_processor = CommandProcessor.new(self)
  @process_controller = ProcessController.new(self)

  @verbose = Shell.verbose
  @debug = Shell.debug
end
notify(*opts) { |mes| ... } click to toggle source
# File lib/shell.rb, line 392
  def self.notify(*opts)
    Shell::debug_output_synchronize do
      if opts[-1].kind_of?(String)
        yorn = verbose?
      else
        yorn = opts.pop
      end
      return unless yorn

      if @debug_display_thread_id
        if @debug_display_process_id
          prefix = "shell(##{Process.pid}:#{Thread.current.to_s.sub("Thread", "Th")}): "
        else
          prefix = "shell(#{Thread.current.to_s.sub("Thread", "Th")}): "
        end
      else
        prefix = "shell: "
      end
      _head = true
      STDERR.print opts.collect{|mes|
        mes = mes.dup
        yield mes if iterator?
        if _head
          _head = false
#         "shell" " + mes
          prefix + mes
        else
          " "* prefix.size + mes
        end
      }.join("\n")+"\n"
    end
  end
unalias_command(ali) click to toggle source

Convenience method for Shell::CommandProcessor.unalias_command

# File lib/shell.rb, line 374
def Shell.unalias_command(ali)
  CommandProcessor.unalias_command(ali)
end
undef_system_command(command) click to toggle source

Convenience method for Shell::CommandProcessor.undef_system_command

# File lib/shell.rb, line 364
def Shell.undef_system_command(command)
  CommandProcessor.undef_system_command(command)
end

Public Instance Methods

cd(path = nil, verbose = @verbose) click to toggle source
Alias for: chdir
chdir(path) click to toggle source

Creates a Shell object which current directory is set to path.

If a block is given, it restores the current directory when the block ends.

If called as iterator, it restores the current directory when the block ends.

# File lib/shell.rb, line 262
def chdir(path = nil, verbose = @verbose)
  check_point

  if iterator?
    notify("chdir(with block) #{path}") if verbose
    cwd_old = @cwd
    begin
      chdir(path, nil)
      yield
    ensure
      chdir(cwd_old, nil)
    end
  else
    notify("chdir #{path}") if verbose
    path = "~" unless path
    @cwd = expand_path(path)
    notify "current dir: #{@cwd}"
    rehash
    Void.new(self)
  end
end
Also aliased as: cd
debug=(val) click to toggle source
# File lib/shell.rb, line 217
def debug=(val)
  @debug = val
  @verbose = val if val
end
expand_path(path) click to toggle source
# File lib/shell.rb, line 228
def expand_path(path)
  File.expand_path(path, @cwd)
end
inspect() click to toggle source
# File lib/shell.rb, line 384
def inspect
  if debug.kind_of?(Integer) && debug > 2
    super
  else
    to_s
  end
end
jobs() click to toggle source

Returns a list of scheduled jobs.

# File lib/shell.rb, line 346
def jobs
  @process_controller.jobs
end
kill(signal, job) click to toggle source

Sends the given signal to the given job

# File lib/shell.rb, line 354
def kill(sig, command)
  @process_controller.kill_job(sig, command)
end
popd() click to toggle source
Alias for: popdir
popdir() click to toggle source

Pops a directory from the directory stack, and sets the current directory to it.

# File lib/shell.rb, line 330
def popdir
  check_point

  notify("popdir")
  if pop = @dir_stack.pop
    chdir pop
    notify "dir stack: [#{@dir_stack.join ', '}]"
    self
  else
    Shell.Fail DirStackEmpty
  end
  Void.new(self)
end
Also aliased as: popd
pushd(path = nil, verbose = @verbose) click to toggle source
Alias for: pushdir
pushdir(path) click to toggle source
pushdir(path) { &block }

Pushes the current directory to the directory stack, changing the current directory to path.

If path is omitted, it exchanges its current directory and the top of its directory stack.

If a block is given, it restores the current directory when the block ends.

# File lib/shell.rb, line 296
def pushdir(path = nil, verbose = @verbose)
  check_point

  if iterator?
    notify("pushdir(with block) #{path}") if verbose
    pushdir(path, nil)
    begin
      yield
    ensure
      popdir
    end
  elsif path
    notify("pushdir #{path}") if verbose
    @dir_stack.push @cwd
    chdir(path, nil)
    notify "dir stack: [#{@dir_stack.join ', '}]"
    self
  else
    notify("pushdir") if verbose
    if pop = @dir_stack.pop
      @dir_stack.push @cwd
      chdir pop
      notify "dir stack: [#{@dir_stack.join ', '}]"
      self
    else
      Shell.Fail DirStackEmpty
    end
  end
  Void.new(self)
end
Also aliased as: pushd
system_path=(path) click to toggle source

Sets the system path (the Shell instance's PATH environment variable).

path should be an array of directory name strings.

# File lib/shell.rb, line 206
def system_path=(path)
  @system_path = path
  rehash
end


class Shell::AppendFile - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::AppendFile

In Files

  • lib/shell/builtin-command.rb

Parent

Shell::AppendIO

Public Class Methods

new(sh, to_filename, filter) click to toggle source
# File lib/shell/builtin-command.rb, line 117
def initialize(sh, to_filename, filter)
  @file_name = to_filename
  io = sh.open(to_filename, "a")
  super(sh, io, filter)
end

Public Instance Methods

input=(filter) click to toggle source
# File lib/shell/builtin-command.rb, line 123
def input=(filter)
  begin
    super
  ensure
    @io.close
  end
end


class Shell::AppendIO - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::AppendIO

class Sort < Cat

def initialize(sh, *filenames)
  super
end

def each(rs = nil)
  ary = []
  super{|l|       ary.push l}
  for l in ary.sort!
  yield l
  end
end

end

In Files

  • lib/shell/builtin-command.rb

Parent

Shell::BuiltInCommand

Public Class Methods

new(sh, io, filter) click to toggle source
# File lib/shell/builtin-command.rb, line 101
def initialize(sh, io, filter)
  super sh
  @input = filter
  @io = io
end

Public Instance Methods

input=(filter) click to toggle source
# File lib/shell/builtin-command.rb, line 107
def input=(filter)
  @input.input=filter
  for l in @input
    @io << l
  end
end


class Shell::BuiltInCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::BuiltInCommand

In Files

  • lib/shell/builtin-command.rb

Parent

Filter

Public Instance Methods

active?() click to toggle source
# File lib/shell/builtin-command.rb, line 19
def active?
  true
end
wait?() click to toggle source
# File lib/shell/builtin-command.rb, line 16
def wait?
  false
end


class Shell::Cat - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::Cat

In Files

  • lib/shell/builtin-command.rb

Parent

Shell::BuiltInCommand

Public Class Methods

new(sh, *filenames) click to toggle source
# File lib/shell/builtin-command.rb, line 49
def initialize(sh, *filenames)
  super sh
  @cat_files = filenames
end

Public Instance Methods

each(rs = nil) { |l| ... } click to toggle source
# File lib/shell/builtin-command.rb, line 54
def each(rs = nil)
  if @cat_files.empty?
    super
  else
    for src in @cat_files
      @shell.foreach(src, rs){|l| yield l}
    end
  end
end


class Shell::CommandProcessor - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::CommandProcessor

In order to execute a command on your OS, you need to define it as a Shell method.

Alternatively, you can execute any command via #system even if it is not defined.

In Files

  • lib/shell/command-processor.rb

Parent

Object

Constants

NoDelegateMethods

Public Class Methods

alias_command(alias, command, *options) → self click to toggle source

Creates a command alias at the given alias for the given command, passing any options along with it.

Shell::CommandProcessor.alias_command "lsC", "ls", "-CBF", "--show-control-chars"
Shell::CommandProcessor.alias_command("lsC", "ls"){|*opts| ["-CBF", "--show-control-chars", *opts]}

# File lib/shell/command-processor.rb, line 432
def self.alias_command(ali, command, *opts)
  ali = ali.id2name if ali.kind_of?(Symbol)
  command = command.id2name if command.kind_of?(Symbol)
  begin
    if iterator?
      @alias_map[ali.intern] = proc

      eval((d = %Q[def #{ali}(*opts)
                      @shell.__send__(:#{command},
                                      *(CommandProcessor.alias_map[:#{ali}].call *opts))
                    end]), nil, __FILE__, __LINE__ - 1)

    else
       args = opts.collect{|opt| '"' + opt + '"'}.join(",")
       eval((d = %Q[def #{ali}(*opts)
                      @shell.__send__(:#{command}, #{args}, *opts)
                    end]), nil, __FILE__, __LINE__ - 1)
    end
  rescue SyntaxError
    Shell.notify "warn: Can't alias #{ali} command: #{command}."
    Shell.notify("Definition of #{ali}: ", d)
    raise
  end
  Shell.notify "Define #{ali} command: #{command}.", Shell.debug?
  Shell.notify("Definition of #{ali}: ", d,
         Shell.debug.kind_of?(Integer) && Shell.debug > 1)
  self
end
alias_map() click to toggle source

Returns a list of aliased commands

# File lib/shell/command-processor.rb, line 420
def self.alias_map
  @alias_map
end
def_system_command(command, path) → Shell::SystemCommand click to toggle source

Defines a command, registering path as a Shell method for the given command.

Shell::CommandProcessor.def_system_command "ls"
  #=> Defines ls.

Shell::CommandProcessor.def_system_command "sys_sort", "sort"
  #=> Defines sys_sort as sort

# File lib/shell/command-processor.rb, line 393
def self.def_system_command(command, path = command)
  begin
    eval((d = %Q[def #{command}(*opts)
              SystemCommand.new(@shell, '#{path}', *opts)
           end]), nil, __FILE__, __LINE__ - 1)
  rescue SyntaxError
    Shell.notify "warn: Can't define #{command} path: #{path}."
  end
  Shell.notify "Define #{command} path: #{path}.", Shell.debug?
  Shell.notify("Definition of #{command}: ", d,
         Shell.debug.kind_of?(Integer) && Shell.debug > 1)
end
initialize() click to toggle source
# File lib/shell/command-processor.rb, line 39
def self.initialize

  install_builtin_commands

  # define CommandProcessor#methods to Shell#methods and Filter#methods
  for m in CommandProcessor.instance_methods(false) - NoDelegateMethods
    add_delegate_command_to_shell(m)
  end

  def self.method_added(id)
    add_delegate_command_to_shell(id)
  end
end
method_added(id) click to toggle source
# File lib/shell/command-processor.rb, line 48
def self.method_added(id)
  add_delegate_command_to_shell(id)
end
new(shell) click to toggle source
# File lib/shell/command-processor.rb, line 69
def initialize(shell)
  @shell = shell
  @system_commands = {}
end
run_config() click to toggle source

include run file.

# File lib/shell/command-processor.rb, line 56
def self.run_config
  begin
    load File.expand_path("~/.rb_shell") if ENV.key?("HOME")
  rescue LoadError, Errno::ENOENT
  rescue
    print "load error: #{rc}\n"
    print $!.class, ": ", $!, "\n"
    for err in $@[0, $@.size - 2]
      print "\t", err, "\n"
    end
  end
end
unalias_command(alias) → self click to toggle source

Unaliases the given alias command.

# File lib/shell/command-processor.rb, line 465
def self.unalias_command(ali)
  ali = ali.id2name if ali.kind_of?(Symbol)
  @alias_map.delete ali.intern
  undef_system_command(ali)
end
undef_system_command(command) → self click to toggle source

Undefines a command

# File lib/shell/command-processor.rb, line 410
def self.undef_system_command(command)
  command = command.id2name if command.kind_of?(Symbol)
  remove_method(command)
  Shell.module_eval{remove_method(command)}
  Filter.module_eval{remove_method(command)}
  self
end

Public Instance Methods

[](command, file1, file2=nil) click to toggle source

See #test

Alias for: test
append(to, filter) click to toggle source
# File lib/shell/command-processor.rb, line 317
def append(to, filter)
  case to
  when String
    AppendFile.new(@shell, to, filter)
  when IO
    AppendIO.new(@shell, to, filter)
  else
    Shell.Fail Error::CantApplyMethod, "append", to.class
  end
end
cat(*filename) → Cat click to toggle source

Returns a Cat object, for the given filenames

# File lib/shell/command-processor.rb, line 302
def cat(*filenames)
  Cat.new(@shell, *filenames)
end
concat(*jobs) → Concat click to toggle source

Returns a Concat object, for the given jobs

# File lib/shell/command-processor.rb, line 340
def concat(*jobs)
  Concat.new(@shell, *jobs)
end
echo(*strings) → Echo click to toggle source

Returns a Echo object, for the given strings

# File lib/shell/command-processor.rb, line 294
def echo(*strings)
  Echo.new(@shell, *strings)
end
expand_path(path) click to toggle source

#expand_path

  path:   String
  return: String
returns the absolute path for <path>
# File lib/shell/command-processor.rb, line 80
def expand_path(path)
  @shell.expand_path(path)
end
find_system_command(command) click to toggle source

private functions

# File lib/shell/command-processor.rb, line 357
def find_system_command(command)
  return command if /^\// =~ command
  case path = @system_commands[command]
  when String
    if exists?(path)
      return path
    else
      Shell.Fail Error::CommandNotFound, command
    end
  when false
    Shell.Fail Error::CommandNotFound, command
  end

  for p in @shell.system_path
    path = join(p, command)
    if FileTest.exist?(path)
      @system_commands[command] = path
      return path
    end
  end
  @system_commands[command] = false
  Shell.Fail Error::CommandNotFound, command
end
foreach(path, record_separator) → Enumerator click to toggle source
foreach(path, record_separator) { block }

See IO.foreach when path is a file.

See Dir.foreach when path is a directory.

# File lib/shell/command-processor.rb, line 92
def foreach(path = nil, *rs)
  path = "." unless path
  path = expand_path(path)

  if File.directory?(path)
    Dir.foreach(path){|fn| yield fn}
  else
    IO.foreach(path, *rs){|l| yield l}
  end
end
glob(pattern) → Glob click to toggle source
def sort(*filenames)
  Sort.new(self, *filenames)
end

Returns a Glob filter object, with the given pattern object

# File lib/shell/command-processor.rb, line 313
def glob(pattern)
  Glob.new(@shell, pattern)
end
mkdir(path) click to toggle source

Same as Object#mkdir, except multiple directories are allowed.

# File lib/shell/command-processor.rb, line 199
def mkdir(*path)
  @shell.check_point
  notify("mkdir #{path.join(' ')}")

  perm = nil
  if path.last.kind_of?(Integer)
    perm = path.pop
  end
  for dir in path
    d = expand_path(dir)
    if perm
      Dir.mkdir(d, perm)
    else
      Dir.mkdir(d)
    end
    File.chmod(d, 0666 & ~@shell.umask) if @shell.umask
  end
  Void.new(@shell)
end
notify(*opts) { |mes| ... } click to toggle source

%pwd, %cwd -> @pwd

# File lib/shell/command-processor.rb, line 345
def notify(*opts)
  Shell.notify(*opts) {|mes|
    yield mes if iterator?

    mes.gsub!("%pwd", "#{@cwd}")
    mes.gsub!("%cwd", "#{@cwd}")
  }
end
open(path, mode, permissions) → Enumerator click to toggle source
open(path, mode, permissions) { block }

See IO.open when path is a file.

See Dir.open when path is a directory.

# File lib/shell/command-processor.rb, line 111
def open(path, mode = nil, perm = 0666, &b)
  path = expand_path(path)
  if File.directory?(path)
    Dir.open(path, &b)
  else
    if @shell.umask
      f = File.open(path, mode, perm)
      File.chmod(perm & ~@shell.umask, path)
      if block_given?
        f.each(&b)
      end
      f
    else
      f = File.open(path, mode, perm, &b)
    end
  end
end
out(device) { block } click to toggle source

Calls device.print on the result passing the block to transact

# File lib/shell/command-processor.rb, line 286
def out(dev = STDOUT, &block)
  dev.print transact(&block)
end
rehash click to toggle source

Clears the command hash table.

# File lib/shell/command-processor.rb, line 257
def rehash
  @system_commands = {}
end
rmdir(path) click to toggle source

Same as Object#rmdir, except multiple directories are allowed.

# File lib/shell/command-processor.rb, line 223
def rmdir(*path)
  @shell.check_point
  notify("rmdir #{path.join(' ')}")

  for dir in path
    Dir.rmdir(expand_path(dir))
  end
  Void.new(@shell)
end
system(command, *options) → SystemCommand click to toggle source

Executes the given command with the options parameter.

Example:

print sh.system("ls", "-l")
sh.system("ls", "-l") | sh.head > STDOUT
# File lib/shell/command-processor.rb, line 242
def system(command, *opts)
  if opts.empty?
    if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\|\$|;|'|`|"|\n/
      return SystemCommand.new(@shell, find_system_command("sh"), "-c", command)
    else
      command, *opts = command.split(/\s+/)
    end
  end
  SystemCommand.new(@shell, find_system_command(command), *opts)
end
tee(file) → Tee click to toggle source

Returns a Tee filter object, with the given file command

# File lib/shell/command-processor.rb, line 332
def tee(file)
  Tee.new(@shell, file)
end
test(command, file1, file2) → true or false click to toggle source
[command, file1, file2] → true or false

Tests if the given command exists in file1, or optionally file2.

Example:

sh[?e, "foo"]
sh[:e, "foo"]
sh["e", "foo"]
sh[:exists?, "foo"]
sh["exists?", "foo"]
# File lib/shell/command-processor.rb, line 164
def test(command, file1, file2=nil)
  file1 = expand_path(file1)
  file2 = expand_path(file2) if file2
  command = command.id2name if command.kind_of?(Symbol)

  case command
  when Integer
    if file2
      top_level_test(command, file1, file2)
    else
      top_level_test(command, file1)
    end
  when String
    if command.size == 1
      if file2
        top_level_test(command, file1, file2)
      else
        top_level_test(command, file1)
      end
    else
      if file2
        FileTest.send(command, file1, file2)
      else
        FileTest.send(command, file1)
      end
    end
  end
end
Also aliased as: top_level_test, []
top_level_test(command, file1, file2=nil) click to toggle source

See #test

Alias for: test
transact { block } click to toggle source

Executes a block as self

Example:

sh.transact { system("ls", "-l") | head > STDOUT }
# File lib/shell/command-processor.rb, line 273
def transact(&block)
  begin
    @shell.instance_eval(&block)
  ensure
    check_point
  end
end
unlink(path) click to toggle source

See IO.unlink when path is a file.

See Dir.unlink when path is a directory.

# File lib/shell/command-processor.rb, line 137
def unlink(path)
  @shell.check_point

  path = expand_path(path)
  if File.directory?(path)
    Dir.unlink(path)
  else
    IO.unlink(path)
  end
  Void.new(@shell)
end


class Shell::Concat - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::Concat

In Files

  • lib/shell/builtin-command.rb

Parent

Shell::BuiltInCommand

Public Class Methods

new(sh, *jobs) click to toggle source
# File lib/shell/builtin-command.rb, line 149
def initialize(sh, *jobs)
  super(sh)
  @jobs = jobs
end

Public Instance Methods

each(rs = nil) { |l| ... } click to toggle source
# File lib/shell/builtin-command.rb, line 154
def each(rs = nil)
  while job = @jobs.shift
    job.each{|l| yield l}
  end
end


class Shell::Echo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::Echo

In Files

  • lib/shell/builtin-command.rb

Parent

Shell::BuiltInCommand

Public Class Methods

new(sh, *strings) click to toggle source
# File lib/shell/builtin-command.rb, line 35
def initialize(sh, *strings)
  super sh
  @strings = strings
end

Public Instance Methods

each(rs = nil) { |str| ... } click to toggle source
# File lib/shell/builtin-command.rb, line 40
def each(rs = nil)
  rs =  @shell.record_separator unless rs
  for str  in @strings
    yield str + rs
  end
end


module Shell::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Shell::Error

In Files

  • lib/shell/error.rb


class Shell::Filter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::Filter

Any result of command exection is a Filter.

This class includes Enumerable, therefore a Filter object can use all Enumerable facilities.

In Files

  • lib/shell/filter.rb

Parent

Object

Included Modules

  • Enumerable

Attributes

input[R]

Public Class Methods

new(sh) click to toggle source
# File lib/shell/filter.rb, line 22
def initialize(sh)
  @shell = sh         # parent shell
  @input = nil        # input filter
end

Public Instance Methods

filter1 + filter2 click to toggle source

Outputs filter1, and then filter2 using Join.new

# File lib/shell/filter.rb, line 113
def + (filter)
  Join.new(@shell, self, filter)
end
< source click to toggle source

Inputs from source, which is either a string of a file name or an IO object.

# File lib/shell/filter.rb, line 49
def < (src)
  case src
  when String
    cat = Cat.new(@shell, src)
    cat | self
  when IO
    self.input = src
    self
  else
    Shell.Fail Error::CantApplyMethod, "<", to.class
  end
end
> source click to toggle source

Outputs from source, which is either a string of a file name or an IO object.

# File lib/shell/filter.rb, line 67
def > (to)
  case to
  when String
    dst = @shell.open(to, "w")
    begin
      each(){|l| dst << l}
    ensure
      dst.close
    end
  when IO
    each(){|l| to << l}
  else
    Shell.Fail Error::CantApplyMethod, ">", to.class
  end
  self
end
>> source click to toggle source

Appends the output to source, which is either a string of a file name or an IO object.

# File lib/shell/filter.rb, line 89
def >> (to)
  begin
    Shell.cd(@shell.pwd).append(to, self)
  rescue CantApplyMethod
    Shell.Fail Error::CantApplyMethod, ">>", to.class
  end
end
each(record_separator=nil) { block } click to toggle source

Iterates a block for each line.

# File lib/shell/filter.rb, line 37
def each(rs = nil)
  rs = @shell.record_separator unless rs
  if @input
    @input.each(rs){|l| yield l}
  end
end
input=(filter) click to toggle source
# File lib/shell/filter.rb, line 29
def input=(filter)
  @input = filter
end
inspect() click to toggle source
# File lib/shell/filter.rb, line 129
def inspect
  if @shell.debug.kind_of?(Integer) && @shell.debug > 2
    super
  else
    to_s
  end
end
to_a() click to toggle source
# File lib/shell/filter.rb, line 117
def to_a
  ary = []
  each(){|l| ary.push l}
  ary
end
to_s() click to toggle source
# File lib/shell/filter.rb, line 123
def to_s
  str = ""
  each(){|l| str.concat l}
  str
end
| filter click to toggle source

Processes a pipeline.

# File lib/shell/filter.rb, line 101
def | (filter)
  filter.input = self
  if active?
    @shell.process_controller.start_job filter
  end
  filter
end


class Shell::Glob - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::Glob

In Files

  • lib/shell/builtin-command.rb

Parent

Shell::BuiltInCommand

Public Class Methods

new(sh, pattern) click to toggle source
# File lib/shell/builtin-command.rb, line 66
def initialize(sh, pattern)
  super sh

  @pattern = pattern
end

Public Instance Methods

each(rs = nil) { |f| ... } click to toggle source
# File lib/shell/builtin-command.rb, line 72
def each(rs = nil)
  if @pattern[0] == /
    @files = Dir[@pattern]
  else
    prefix = @shell.pwd+"/"
    @files = Dir[prefix+@pattern].collect{|p| p.sub(prefix, "")}
  end
  rs =  @shell.record_separator unless rs
  for f in @files
    yield f+rs
  end
end


class Shell::ProcessController - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::ProcessController

In Files

  • lib/shell/process-controller.rb

Parent

Object

Constants

USING_AT_EXIT_WHEN_PROCESS_EXIT

for shell-command complete finish at this process exit.

Attributes

shell[R]

Public Class Methods

activate(pc) click to toggle source
# File lib/shell/process-controller.rb, line 38
def activate(pc)
  process_controllers_exclusive do
    @ProcessControllers[pc] ||= 0
    @ProcessControllers[pc] += 1
  end
end
active_process_controllers() click to toggle source
# File lib/shell/process-controller.rb, line 32
def active_process_controllers
  process_controllers_exclusive do
    @ProcessControllers.dup
  end
end
block_output_synchronize(&b) click to toggle source
# File lib/shell/process-controller.rb, line 64
def block_output_synchronize(&b)
  @BlockOutputMonitor.synchronize(&b)
end
each_active_object() { |ref| ... } click to toggle source
# File lib/shell/process-controller.rb, line 56
def each_active_object
  process_controllers_exclusive do
    for ref in @ProcessControllers.keys
      yield ref
    end
  end
end
inactivate(pc) click to toggle source
# File lib/shell/process-controller.rb, line 45
def inactivate(pc)
  process_controllers_exclusive do
    if @ProcessControllers[pc]
      if (@ProcessControllers[pc] -= 1) == 0
        @ProcessControllers.delete(pc)
        @ProcessControllersCV.signal
      end
    end
  end
end
new(shell) click to toggle source
# File lib/shell/process-controller.rb, line 93
def initialize(shell)
  @shell = shell
  @waiting_jobs = []
  @active_jobs = []
  @jobs_sync = Sync.new

  @job_monitor = Mutex.new
  @job_condition = ConditionVariable.new
end
wait_to_finish_all_process_controllers() click to toggle source
# File lib/shell/process-controller.rb, line 68
def wait_to_finish_all_process_controllers
  process_controllers_exclusive do
    while !@ProcessControllers.empty?
      Shell::notify("Process finishing, but active shell exists",
                    "You can use Shell#transact or Shell#check_point for more safe execution.")
      if Shell.debug?
        for pc in @ProcessControllers.keys
          Shell::notify(" Not finished jobs in "+pc.shell.to_s)
          for com in pc.jobs
            com.notify("  Jobs: %id")
          end
        end
      end
      @ProcessControllersCV.wait(@ProcessControllersMonitor)
    end
  end
end

Public Instance Methods

active_job?(job) click to toggle source
# File lib/shell/process-controller.rb, line 182
def active_job?(job)
  @jobs_sync.synchronize(:SH) do
    @active_jobs.include?(job)
  end
end
active_jobs() click to toggle source
# File lib/shell/process-controller.rb, line 114
def active_jobs
  @active_jobs
end
active_jobs_exist?() click to toggle source
# File lib/shell/process-controller.rb, line 128
def active_jobs_exist?
  @jobs_sync.synchronize(:SH) do
    @active_jobs.empty?
  end
end
add_schedule(command) click to toggle source

schedule a command

# File lib/shell/process-controller.rb, line 141
def add_schedule(command)
  @jobs_sync.synchronize(:EX) do
    ProcessController.activate(self)
    if @active_jobs.empty?
      start_job command
    else
      @waiting_jobs.push(command)
    end
  end
end
jobs() click to toggle source
# File lib/shell/process-controller.rb, line 105
def jobs
  jobs = []
  @jobs_sync.synchronize(:SH) do
    jobs.concat @waiting_jobs
    jobs.concat @active_jobs
  end
  jobs
end
jobs_exist?() click to toggle source
# File lib/shell/process-controller.rb, line 122
def jobs_exist?
  @jobs_sync.synchronize(:SH) do
    @active_jobs.empty? or @waiting_jobs.empty?
  end
end
kill_job(sig, command) click to toggle source

kill a job

# File lib/shell/process-controller.rb, line 201
def kill_job(sig, command)
  @jobs_sync.synchronize(:EX) do
    if @waiting_jobs.delete command
      ProcessController.inactivate(self)
      return
    elsif @active_jobs.include?(command)
      begin
        r = command.kill(sig)
        ProcessController.inactivate(self)
      rescue
        print "Shell: Warn: $!\n" if @shell.verbose?
        return nil
      end
      @active_jobs.delete command
      r
    end
  end
end
sfork(command) { || ... } click to toggle source

simple fork

# File lib/shell/process-controller.rb, line 237
    def sfork(command)
      pipe_me_in, pipe_peer_out = IO.pipe
      pipe_peer_in, pipe_me_out = IO.pipe

      pid = nil
      pid_mutex = Mutex.new
      pid_cv = ConditionVariable.new

      Thread.start do
        ProcessController.block_output_synchronize do
          STDOUT.flush
          ProcessController.each_active_object do |pc|
            for jobs in pc.active_jobs
              jobs.flush
            end
          end

          pid = fork {
            Thread.list.each do |th|
#             th.kill unless [Thread.main, Thread.current].include?(th)
              th.kill unless Thread.current == th
            end

            STDIN.reopen(pipe_peer_in)
            STDOUT.reopen(pipe_peer_out)

            ObjectSpace.each_object(IO) do |io|
              if ![STDIN, STDOUT, STDERR].include?(io)
                io.close unless io.closed?
              end
            end

            yield
          }
        end
        pid_cv.signal

        pipe_peer_in.close
        pipe_peer_out.close
        command.notify "job(%name:##{pid}) start", @shell.debug?

        begin
          _pid = nil
          command.notify("job(%id) start to waiting finish.", @shell.debug?)
          _pid = Process.waitpid(pid, nil)
        rescue Errno::ECHILD
          command.notify "warn: job(%id) was done already waitpid."
          _pid = true
          #     rescue
          #       STDERR.puts $!
        ensure
          command.notify("Job(%id): Wait to finish when Process finished.", @shell.debug?)
          # when the process ends, wait until the command terminates
          if USING_AT_EXIT_WHEN_PROCESS_EXIT or _pid
          else
            command.notify("notice: Process finishing...",
                           "wait for Job[%id] to finish.",
                           "You can use Shell#transact or Shell#check_point for more safe execution.")
            redo
          end

#         command.notify "job(%id) pre-pre-finish.", @shell.debug?
          @job_monitor.synchronize do
#           command.notify "job(%id) pre-finish.", @shell.debug?
            terminate_job(command)
#           command.notify "job(%id) pre-finish2.", @shell.debug?
            @job_condition.signal
            command.notify "job(%id) finish.", @shell.debug?
          end
        end
      end

      pid_mutex.synchronize do
        while !pid
          pid_cv.wait(pid_mutex)
        end
      end

      return pid, pipe_me_in, pipe_me_out
    end
start_job(command = nil) click to toggle source

start a job

# File lib/shell/process-controller.rb, line 153
    def start_job(command = nil)
      @jobs_sync.synchronize(:EX) do
        if command
          return if command.active?
          @waiting_jobs.delete command
        else
          command = @waiting_jobs.shift
#         command.notify "job(%id) pre-start.", @shell.debug?

          return unless command
        end
        @active_jobs.push command
        command.start
#       command.notify "job(%id) post-start.", @shell.debug?

        # start all jobs that input from the job
        for job in @waiting_jobs.dup
          start_job(job) if job.input == command
        end
#       command.notify "job(%id) post2-start.", @shell.debug?
      end
    end
terminate_job(command) click to toggle source

terminate a job

# File lib/shell/process-controller.rb, line 189
def terminate_job(command)
  @jobs_sync.synchronize(:EX) do
    @active_jobs.delete command
    ProcessController.inactivate(self)
    if @active_jobs.empty?
      command.notify("start_job in terminate_job(%id)", Shell::debug?)
      start_job
    end
  end
end
wait_all_jobs_execution() click to toggle source

wait for all jobs to terminate

# File lib/shell/process-controller.rb, line 221
def wait_all_jobs_execution
  @job_monitor.synchronize do
    begin
      while !jobs.empty?
        @job_condition.wait(@job_monitor)
        for job in jobs
          job.notify("waiting job(%id)", Shell::debug?)
        end
      end
    ensure
      redo unless jobs.empty?
    end
  end
end
waiting_job?(job) click to toggle source
# File lib/shell/process-controller.rb, line 176
def waiting_job?(job)
  @jobs_sync.synchronize(:SH) do
    @waiting_jobs.include?(job)
  end
end
waiting_jobs() click to toggle source
# File lib/shell/process-controller.rb, line 118
def waiting_jobs
  @waiting_jobs
end
waiting_jobs_exist?() click to toggle source
# File lib/shell/process-controller.rb, line 134
def waiting_jobs_exist?
  @jobs_sync.synchronize(:SH) do
    @waiting_jobs.empty?
  end
end


class Shell::SystemCommand - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::SystemCommand

In Files

  • lib/shell/system-command.rb

Parent

Shell::Filter

Attributes

command[R]
name[R]

Public Class Methods

new(sh, command, *opts) click to toggle source
# File lib/shell/system-command.rb, line 16
def initialize(sh, command, *opts)
  if t = opts.find{|opt| !opt.kind_of?(String) && opt.class}
    Shell.Fail Error::TypeError, t.class, "String"
  end
  super(sh)
  @command = command
  @opts = opts

  @input_queue = Queue.new
  @pid = nil

  sh.process_controller.add_schedule(self)
end

Public Instance Methods

active?() click to toggle source
# File lib/shell/system-command.rb, line 37
def active?
  @shell.process_controller.active_job?(self)
end
each(rs = nil) { |l| ... } click to toggle source
# File lib/shell/system-command.rb, line 136
def each(rs = nil)
  while (l = @input_queue.pop) != :EOF
    yield l
  end
end
Also aliased as: super_each
flush() click to toggle source
# File lib/shell/system-command.rb, line 62
def flush
  @pipe_out.flush if @pipe_out and !@pipe_out.closed?
end
input=(inp) click to toggle source
# File lib/shell/system-command.rb, line 41
def input=(inp)
  super
  if active?
    start_export
  end
end
kill(sig) click to toggle source
# File lib/shell/system-command.rb, line 77
def kill(sig)
  if @pid
    Process.kill(sig, @pid)
  end
end
notify(*opts) { |mes| ... } click to toggle source

ex)

if you wish to output:
   "shell: job(#{@command}:#{@pid}) close pipe-out."
then
   mes: "job(%id) close pipe-out."
yorn: Boolean(@shell.debug? or @shell.verbose?)
# File lib/shell/system-command.rb, line 148
def notify(*opts)
  @shell.notify(*opts) do |mes|
    yield mes if iterator?

    mes.gsub!("%id", "#{@command}:##{@pid}")
    mes.gsub!("%name", "#{@command}")
    mes.gsub!("%pid", "#{@pid}")
    mes
  end
end
start() click to toggle source
# File lib/shell/system-command.rb, line 48
def start
  notify([@command, *@opts].join(" "))

  @pid, @pipe_in, @pipe_out = @shell.process_controller.sfork(self) {
    Dir.chdir @shell.pwd
    $0 = @command
    exec(@command, *@opts)
  }
  if @input
    start_export
  end
  start_import
end
start_export() click to toggle source
# File lib/shell/system-command.rb, line 109
def start_export
  notify "job(%id) start exp-pipe.", @shell.debug?
  _eop = true
  Thread.start{
    begin
      @input.each do |l|
        ProcessController::block_output_synchronize do
          @pipe_out.print l
        end
      end
      _eop = false
    rescue Errno::EPIPE, Errno::EIO
      _eop = false
    ensure
      if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
        notify("shell: warn: Process finishing...",
               "wait for Job(%id) to finish pipe exporting.",
               "You can use Shell#transact or Shell#check_point for more safe execution.")
        redo
      end
      notify "job(%id) close exp-pipe.", @shell.debug?
      @pipe_out.close
    end
  }
end
start_import() click to toggle source
# File lib/shell/system-command.rb, line 83
def start_import
  notify "Job(%id) start imp-pipe.", @shell.debug?
  rs = @shell.record_separator unless rs
  _eop = true
  Thread.start {
    begin
      while l = @pipe_in.gets
        @input_queue.push l
      end
      _eop = false
    rescue Errno::EPIPE
      _eop = false
    ensure
      if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
        notify("warn: Process finishing...",
               "wait for Job[%id] to finish pipe importing.",
               "You can use Shell#transact or Shell#check_point for more safe execution.")
        redo
      end
      notify "job(%id}) close imp-pipe.", @shell.debug?
      @input_queue.push :EOF
      @pipe_in.close
    end
  }
end
super_each(rs = nil) click to toggle source
Alias for: each
terminate() click to toggle source
# File lib/shell/system-command.rb, line 66
def terminate
  begin
    @pipe_in.close
  rescue IOError
  end
  begin
    @pipe_out.close
  rescue IOError
  end
end
wait?() click to toggle source
# File lib/shell/system-command.rb, line 33
def wait?
  @shell.process_controller.waiting_job?(self)
end


class Shell::Tee - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::Tee

In Files

  • lib/shell/builtin-command.rb

Parent

Shell::BuiltInCommand

Public Class Methods

new(sh, filename) click to toggle source
# File lib/shell/builtin-command.rb, line 133
def initialize(sh, filename)
  super sh
  @to_filename = filename
end

Public Instance Methods

each(rs = nil) { |l| ... } click to toggle source
# File lib/shell/builtin-command.rb, line 138
def each(rs = nil)
  to = @shell.open(@to_filename, "w")
  begin
    super{|l| to << l; yield l}
  ensure
    to.close
  end
end


class Shell::Void - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Shell::Void

In Files

  • lib/shell/builtin-command.rb

Parent

Shell::BuiltInCommand

Public Class Methods

new(sh, *opts) click to toggle source
# File lib/shell/builtin-command.rb, line 25
def initialize(sh, *opts)
  super sh
end

Public Instance Methods

each(rs = nil) click to toggle source
# File lib/shell/builtin-command.rb, line 29
def each(rs = nil)
  # do nothing
end


module Shellwords - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Shellwords

Manipulates strings like the UNIX Bourne shell

This module manipulates strings according to the word parsing rules of the UNIX Bourne shell.

The shellwords() function was originally a port of shellwords.pl, but modified to conform to POSIX / SUSv3 (IEEE Std 1003.1-2001 [1]).

Usage

You can use shellwords to parse a string into a Bourne shell friendly Array.

require 'shellwords'

argv = Shellwords.split('three blind "mice"')
argv #=> ["three", "blind", "mice"]

Once you've required Shellwords, you can use the split alias String#shellsplit.

argv = "see how they run".shellsplit
argv #=> ["see", "how", "they", "run"]

Be careful you don't leave a quote unmatched.

argv = "they all ran after the farmer's wife".shellsplit
     #=> ArgumentError: Unmatched double quote: ...

In this case, you might want to use ::escape, or it's alias String#shellescape.

This method will escape the String for you to safely use with a Bourne shell.

argv = Shellwords.escape("special's.txt")
argv #=> "special\\s.txt"
system("cat " + argv)

Shellwords also comes with a core extension for Array, Array#shelljoin.

argv = %w{ls -lta lib}
system(argv.shelljoin)

You can use this method to create an escaped string out of an array of tokens separated by a space. In this example we'll use the literal shortcut for Array.new.

Authors

  • Wakou Aoyama

  • Akinori MUSHA <knu@iDaemons.org>

Contact

  • Akinori MUSHA <knu@iDaemons.org> (current maintainer)

Resources

1: IEEE Std 1003.1-2004

In Files

  • lib/shellwords.rb

Public Class Methods

escape(str) click to toggle source
Alias for: shellescape
join(array) click to toggle source
Alias for: shelljoin
shellescape(str) click to toggle source

Escapes a string so that it can be safely used in a Bourne shell command line. str can be a non-string object that responds to to_s.

Note that a resulted string should be used unquoted and is not intended for use in double quotes nor in single quotes.

argv = Shellwords.escape("It's better to give than to receive")
argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"

String#shellescape is a shorthand for this function.

argv = "It's better to give than to receive".shellescape
argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"

# Search files in lib for method definitions
pattern = "^[ \t]*def "
open("| grep -Ern #{pattern.shellescape} lib") { |grep|
  grep.each_line { |line|
    file, lineno, matched_line = line.split(':', 3)
    # ...
  }
}

It is the caller's responsibility to encode the string in the right encoding for the shell environment where this string is used.

Multibyte characters are treated as multibyte characters, not bytes.

Returns an empty quoted String if str has a length of zero.

# File lib/shellwords.rb, line 123
def shellescape(str)
  str = str.to_s

  # An empty argument will be skipped, so return empty quotes.
  return "''" if str.empty?

  str = str.dup

  # Treat multibyte characters as is.  It is caller's responsibility
  # to encode the string in the right encoding for the shell
  # environment.
  str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/, "\\\\\\1")

  # A LF cannot be escaped with a backslash because a backslash + LF
  # combo is regarded as line continuation and simply ignored.
  str.gsub!(/\n/, "'\n'")

  return str
end
Also aliased as: escape
shelljoin(array) click to toggle source

Builds a command line string from an argument list, array.

All elements are joined into a single string with fields separated by a space, where each element is escaped for Bourne shell and stringified using to_s.

ary = ["There's", "a", "time", "and", "place", "for", "everything"]
argv = Shellwords.join(ary)
argv #=> "There\\'s a time and place for everything"

Array#shelljoin is a shortcut for this function.

ary = ["Don't", "rock", "the", "boat"]
argv = ary.shelljoin
argv #=> "Don\\'t rock the boat"

You can also mix non-string objects in the elements as allowed in Array#join.

output = `#{['ps', '-p', $$].shelljoin}`
# File lib/shellwords.rb, line 169
def shelljoin(array)
  array.map { |arg| shellescape(arg) }.join(' ')
end
Also aliased as: join
shellsplit(line) click to toggle source

Splits a string into an array of tokens in the same way the UNIX Bourne shell does.

argv = Shellwords.split('here are "two words"')
argv #=> ["here", "are", "two words"]

String#shellsplit is a shortcut for this function.

argv = 'here are "two words"'.shellsplit
argv #=> ["here", "are", "two words"]

# File lib/shellwords.rb, line 70
def shellsplit(line)
  words = []
  field = ''
  line.scan(/\G\s*(?>([^\s\\\"]+)|'([^\]*)'|"((?:[^\"\]|\.)*)"|(\.?)|(\S))(\s|\z)?/) do
    |word, sq, dq, esc, garbage, sep|
    raise ArgumentError, "Unmatched double quote: #{line.inspect}" if garbage
    field << (word || sq || (dq || esc).gsub(/\(.)/, '\1'))
    if sep
      words << field
      field = ''
    end
  end
  words
end
Also aliased as: shellwords, split
shellwords(line) click to toggle source
Alias for: shellsplit
split(line) click to toggle source
Alias for: shellsplit


class SimpleDelegator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class SimpleDelegator

A concrete implementation of Delegator, this class provides the means to delegate all supported method calls to the object passed into the constructor and even to change the object being delegated to at a later time with #__setobj__.

Here's a simple example that takes advantage of the fact that SimpleDelegator's delegation object can be changed at any time.

class Stats
  def initialize
    @source = SimpleDelegator.new([])
  end

  def stats(records)
    @source.__setobj__(records)

    "Elements:  #{@source.size}\n" +
    " Non-Nil:  #{@source.compact.size}\n" +
    "  Unique:  #{@source.uniq.size}\n"
  end
end

s = Stats.new
puts s.stats(%w{James Edward Gray II})
puts
puts s.stats([1, 2, 3, nil, 4, 5, 1, 2])

Prints:

Elements:  4
 Non-Nil:  4
  Unique:  4

Elements:  8
 Non-Nil:  7
  Unique:  6

In Files

  • lib/delegate.rb

Parent

Delegator

Public Instance Methods

__getobj__() click to toggle source

Returns the current object method calls are being delegated to.

# File lib/delegate.rb, line 267
def __getobj__
  @delegate_sd_obj
end
__setobj__(obj) click to toggle source

Changes the delegate object to obj.

It's important to note that this does not cause SimpleDelegator's methods to change. Because of this, you probably only want to change delegation to objects of the same type as the original delegate.

Here's an example of changing the delegation object.

names = SimpleDelegator.new(%w{James Edward Gray II})
puts names[1]    # => Edward
names.__setobj__(%w{Gavin Sinclair})
puts names[1]    # => Sinclair

# File lib/delegate.rb, line 285
def __setobj__(obj)
  raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
  @delegate_sd_obj = obj
end


module SingleForwardable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module SingleForwardable

SingleForwardable can be used to setup delegation at the object level as well.

printer = String.new
printer.extend SingleForwardable        # prepare object for delegation
printer.def_delegator "STDOUT", "puts"  # add delegation for STDOUT.puts()
printer.puts "Howdy!"

Also, SingleForwardable can be used to set up delegation for a Class or Module.

class Implementation
  def self.service
    puts "serviced!"
  end
end

module Facade
  extend SingleForwardable
  def_delegator :Implementation, :service
end

Facade.service #=> serviced!

If you want to use both Forwardable and SingleForwardable, you can use methods def_instance_delegator and #def_single_delegator, etc.

In Files

  • lib/forwardable.rb

Public Instance Methods

def_delegator(accessor, method, ali = method) click to toggle source
Alias for: def_single_delegator
def_delegators(accessor, *methods) click to toggle source
Alias for: def_single_delegators
def_single_delegator(accessor, method, new_name=method) click to toggle source

Defines a method method which delegates to accessor (i.e. it calls the method of the same name in accessor). If new_name is provided, it is used as the name for the delegate method.

# File lib/forwardable.rb, line 259
def def_single_delegator(accessor, method, ali = method)
  str = %Q{
    def #{ali}(*args, &block)
      begin
        #{accessor}.__send__(:#{method}, *args, &block)
      rescue Exception
        $@.delete_if{|s| %r"#{Regexp.quote(__FILE__)}"o =~ s} unless Forwardable::debug
        ::Kernel::raise
      end
    end
  }

  instance_eval(str, __FILE__, __LINE__)
end
Also aliased as: def_delegator
def_single_delegators(accessor, *methods) click to toggle source

Shortcut for defining multiple delegator methods, but with no provision for using a different name. The following two code samples have the same effect:

def_delegators :@records, :size, :<<, :map

def_delegator :@records, :size
def_delegator :@records, :<<
def_delegator :@records, :map
# File lib/forwardable.rb, line 245
def def_single_delegators(accessor, *methods)
  methods.delete("__send__")
  methods.delete("__id__")
  for method in methods
    def_single_delegator(accessor, method)
  end
end
Also aliased as: def_delegators
delegate(hash) click to toggle source
Alias for: single_delegate
delegate method → accessor click to toggle source
delegate [method, method, ...] → accessor

Takes a hash as its argument. The key is a symbol or an array of symbols. These symbols correspond to method names. The value is the accessor to which the methods will be delegated.

# File lib/forwardable.rb, line 225
def single_delegate(hash)
  hash.each{ |methods, accessor|
    methods = [methods] unless methods.respond_to?(:each)
    methods.each{ |method|
      def_single_delegator(accessor, method)
    }
  }
end
Also aliased as: delegate


module Singleton - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Singleton

The Singleton module implements the Singleton pattern.

Usage

To use Singleton, include the module in your class.

class Klass
   include Singleton
   # ...
end

This ensures that only one instance of Klass can be created.

a,b  = Klass.instance, Klass.instance

a == b
# => true

Klass.new
# => NoMethodError - new is private ...

The instance is created at upon the first call of Klass.instance().

class OtherKlass
  include Singleton
  # ...
end

ObjectSpace.each_object(OtherKlass){}
# => 0

OtherKlass.instance
ObjectSpace.each_object(OtherKlass){}
# => 1

This behavior is preserved under inheritance and cloning.

Implementation

This above is achieved by:

  • Making Klass.new and Klass.allocate private.

  • Overriding Klass.inherited(sub_klass) and Klass.clone() to ensure that the Singleton properties are kept when inherited and cloned.

  • Providing the Klass.instance() method that returns the same object each time it is called.

  • Overriding Klass._load(str) to call Klass.instance().

  • Overriding Klass#clone and Klass#dup to raise TypeErrors to prevent cloning or duping.

Singleton and Marshal

By default Singleton's #_dump(depth) returns the empty string. Marshalling by default will strip state information, e.g. instance variables and taint state, from the instance. Classes using Singleton can provide custom _load(str) and _dump(depth) methods to retain some of the previous state of the instance.

require 'singleton'

class Example
  include Singleton
  attr_accessor :keep, :strip
  def _dump(depth)
    # this strips the @strip information from the instance
    Marshal.dump(@keep, depth)
  end

  def self._load(str)
    instance.keep = Marshal.load(str)
    instance
  end
end

a = Example.instance
a.keep = "keep this"
a.strip = "get rid of this"
a.taint

stored_state = Marshal.dump(a)

a.keep = nil
a.strip = nil
b = Marshal.load(stored_state)
p a == b  #  => true
p a.keep  #  => "keep this"
p a.strip #  => nil

In Files

  • lib/singleton.rb

Public Class Methods

_load() click to toggle source

By default calls instance(). Override to retain singleton state.

# File lib/singleton.rb, line 172

Public Instance Methods

_dump(depth = -1) click to toggle source

By default, do not retain any state when marshalling.

# File lib/singleton.rb, line 108
def _dump(depth = -1)
  ''
end
clone() click to toggle source

Raises a TypeError to prevent cloning.

# File lib/singleton.rb, line 98
def clone
  raise TypeError, "can't clone instance of singleton #{self.class}"
end
dup() click to toggle source

Raises a TypeError to prevent duping.

# File lib/singleton.rb, line 103
def dup
  raise TypeError, "can't dup instance of singleton #{self.class}"
end


class SizedQueue - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class SizedQueue

This class represents queues of specified size capacity. The push operation may be blocked if the capacity is full.

See Queue for an example of how a SizedQueue works.

In Files

  • lib/thread.rb

Parent

Queue

Public Class Methods

new(max) click to toggle source

Creates a fixed-length queue with a maximum size of max.

# File lib/thread.rb, line 263
def initialize(max)
  raise ArgumentError, "queue size must be positive" unless max > 0
  @max = max
  @enque_cond = ConditionVariable.new
  @num_enqueue_waiting = 0
  super()
end

Public Instance Methods

<<(obj) click to toggle source

Alias of push

Alias for: push
clear() click to toggle source

Removes all objects from the queue.

# File lib/thread.rb, line 324
def clear
  super
  @mutex.synchronize do
    @max.times do
      @enque_cond.signal
    end
  end
end
deq(*args) click to toggle source

Alias of pop

Alias for: pop
enq(obj) click to toggle source

Alias of push

Alias for: push
max() click to toggle source

Returns the maximum size of the queue.

# File lib/thread.rb, line 274
def max
  @max
end
max=(max) click to toggle source

Sets the maximum size of the queue.

# File lib/thread.rb, line 281
def max=(max)
  raise ArgumentError, "queue size must be positive" unless max > 0

  @mutex.synchronize do
    if max <= @max
      @max = max
    else
      diff = max - @max
      @max = max
      diff.times do
        @enque_cond.signal
      end
    end
  end
  max
end
num_waiting() click to toggle source

Returns the number of threads waiting on the queue.

# File lib/thread.rb, line 369
def num_waiting
  @num_waiting + @num_enqueue_waiting
end
pop(*args) click to toggle source

Retrieves data from the queue and runs a waiting thread, if any.

# File lib/thread.rb, line 346
def pop(*args)
  retval = super
  @mutex.synchronize do
    if @que.length < @max
      @enque_cond.signal
    end
  end
  retval
end
Also aliased as: shift, deq
push(obj) click to toggle source

Pushes obj to the queue. If there is no space left in the queue, waits until space becomes available.

# File lib/thread.rb, line 302
def push(obj)
  Thread.handle_interrupt(RuntimeError => :on_blocking) do
    @mutex.synchronize do
      while true
        break if @que.length < @max
        @num_enqueue_waiting += 1
        begin
          @enque_cond.wait @mutex
        ensure
          @num_enqueue_waiting -= 1
        end
      end

      @que.push obj
      @cond.signal
    end
  end
end
Also aliased as: <<, enq
shift(*args) click to toggle source

Alias of pop

Alias for: pop


class Socket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Socket

Class Socket provides access to the underlying operating system socket implementations. It can be used to provide more operating system specific functionality than the protocol-specific socket classes.

The constants defined under Socket::Constants are also defined under Socket. For example, Socket::AF_INET is usable as well as Socket::Constants::AF_INET. See Socket::Constants for the list of constants.

What's a socket?

Sockets are endpoints of a bidirectionnal communication channel. Sockets can communicate within a process, between processes on the same machine or between different machines. There are many types of socket: TCPSocket, UDPSocket or UNIXSocket for example.

Sockets have their own vocabulary:

domain: The family of protocols:

  • Socket::PF_INET

  • Socket::PF_INET6

  • Socket::PF_UNIX

  • etc.

type: The type of communications between the two endpoints, typically

  • Socket::SOCK_STREAM

  • Socket::SOCK_DGRAM.

protocol: Typically zero. This may be used to identify a variant of a protocol.

hostname: The identifier of a network interface:

  • a string (hostname, IPv4 or IPv6 adress or broadcast which specifies a broadcast address)

  • a zero-length string which specifies INADDR_ANY

  • an integer (interpreted as binary address in host byte order).

Quick start

Many of the classes, such as TCPSocket, UDPSocket or UNIXSocket, ease the use of sockets comparatively to the equivalent C programming interface.

Let's create an internet socket using the IPv4 protocol in a C-like manner:

s = Socket.new Socket::AF_INET, Socket::SOCK_STREAM
s.connect Socket.pack_sockaddr_in(80, 'example.com')

You could also use the TCPSocket class:

s = TCPSocket.new 'example.com', 80

A simple server might look like this:

require 'socket'

server = TCPServer.new 2000 # Server bound to port 2000

loop do
  client = server.accept    # Wait for a client to connect
  client.puts "Hello !"
  client.puts "Time is #{Time.now}"
  client.close
end

A simple client may look like this:

require 'socket'

s = TCPSocket.new 'localhost', 2000

while line = s.gets # Read lines from socket
  puts line         # and print them
end

s.close             # close socket when done

Exception Handling

Ruby's Socket implementation raises exceptions based on the error generated by the system dependent implementation. This is why the methods are documented in a way that isolate Unix-based system exceptions from Windows based exceptions. If more information on a particular exception is needed, please refer to the Unix manual pages or the Windows WinSock reference.

Convenience methods

Although the general way to create socket is ::new, there are several methods of socket creation for most cases.

TCP client socket

::tcp, TCPSocket.open

TCP server socket

::tcp_server_loop, TCPServer.open

UNIX client socket

::unix, UNIXSocket.open

UNIX server socket

::unix_server_loop, UNIXServer.open

Documentation by

  • Zach Dennis

  • Sam Roberts

  • Programming Ruby from The Pragmatic Bookshelf.

Much material in this documentation is taken with permission from Programming Ruby from The Pragmatic Bookshelf.

In Files

  • lib/ipaddr.rb
  • ext/socket/ancdata.c
  • ext/socket/socket.c
  • ext/socket/lib/socket.rb

Parent

BasicSocket

Constants

AF_INET6

IPv6 protocol family

Public Class Methods

accept_loop(*sockets) { |socket, client_addrinfo| ... } click to toggle source

yield socket and client address for each a connection accepted via given sockets.

The arguments are a list of sockets. The individual argument should be a socket or an array of sockets.

This method yields the block sequentially. It means that the next connection is not accepted until the block returns. So concurrent mechanism, thread for example, should be used to service multiple clients at a time.

# File ext/socket/lib/socket.rb, line 501
def self.accept_loop(*sockets) # :yield: socket, client_addrinfo
  sockets.flatten!(1)
  if sockets.empty?
    raise ArgumentError, "no sockets"
  end
  loop {
    readable, _, _ = IO.select(sockets)
    readable.each {|r|
      begin
        sock, addr = r.accept_nonblock
      rescue IO::WaitReadable
        next
      end
      yield sock, addr
    }
  }
end
getaddrinfo(nodename, servname[, family[, socktype[, protocol[, flags[, reverse_lookup]]]]]) → array click to toggle source

Obtains address information for nodename:servname.

family should be an address family such as: :INET, :INET6, :UNIX, etc.

socktype should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.

protocol should be a protocol defined in the family, and defaults to 0 for the family.

flags should be bitwise OR of Socket::AI_* constants.

Socket.getaddrinfo("www.ruby-lang.org", "http", nil, :STREAM)
#=> [["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68", 2, 1, 6]] # PF_INET/SOCK_STREAM/IPPROTO_TCP

Socket.getaddrinfo("localhost", nil)
#=> [["AF_INET", 0, "localhost", "127.0.0.1", 2, 1, 6],  # PF_INET/SOCK_STREAM/IPPROTO_TCP
#    ["AF_INET", 0, "localhost", "127.0.0.1", 2, 2, 17], # PF_INET/SOCK_DGRAM/IPPROTO_UDP
#    ["AF_INET", 0, "localhost", "127.0.0.1", 2, 3, 0]]  # PF_INET/SOCK_RAW/IPPROTO_IP

reverse_lookup directs the form of the third element, and has to be one of below. If reverse_lookup is omitted, the default value is nil.

+true+, +:hostname+:  hostname is obtained from numeric address using reverse lookup, which may take a time.
+false+, +:numeric+:  hostname is same as numeric address.
+nil+:              obey to the current +do_not_reverse_lookup+ flag.

If Addrinfo object is preferred, use Addrinfo.getaddrinfo.

static VALUE
sock_s_getaddrinfo(int argc, VALUE *argv)
{
    VALUE host, port, family, socktype, protocol, flags, ret, revlookup;
    struct addrinfo hints, *res;
    int norevlookup;

    rb_scan_args(argc, argv, "25", &host, &port, &family, &socktype, &protocol, &flags, &revlookup);

    MEMZERO(&hints, struct addrinfo, 1);
    hints.ai_family = NIL_P(family) ? PF_UNSPEC : rsock_family_arg(family);

    if (!NIL_P(socktype)) {
        hints.ai_socktype = rsock_socktype_arg(socktype);
    }
    if (!NIL_P(protocol)) {
        hints.ai_protocol = NUM2INT(protocol);
    }
    if (!NIL_P(flags)) {
        hints.ai_flags = NUM2INT(flags);
    }
    if (NIL_P(revlookup) || !rsock_revlookup_flag(revlookup, &norevlookup)) {
        norevlookup = rsock_do_not_reverse_lookup;
    }
    res = rsock_getaddrinfo(host, port, &hints, 0);

    ret = make_addrinfo(res, norevlookup);
    freeaddrinfo(res);
    return ret;
}
gethostbyaddr(address_string [, address_family]) → hostent click to toggle source

Obtains the host information for address.

p Socket.gethostbyaddr([221,186,184,68].pack("CCCC"))
#=> ["carbon.ruby-lang.org", [], 2, "\xDD\xBA\xB8D"]

static VALUE
sock_s_gethostbyaddr(int argc, VALUE *argv)
{
    VALUE addr, family;
    struct hostent *h;
    char **pch;
    VALUE ary, names;
    int t = AF_INET;

    rb_scan_args(argc, argv, "11", &addr, &family);
    StringValue(addr);
    if (!NIL_P(family)) {
        t = rsock_family_arg(family);
    }
#ifdef AF_INET6
    else if (RSTRING_LEN(addr) == 16) {
        t = AF_INET6;
    }
#endif
    h = gethostbyaddr(RSTRING_PTR(addr), RSTRING_LENINT(addr), t);
    if (h == NULL) {
#ifdef HAVE_HSTRERROR
        extern int h_errno;
        rb_raise(rb_eSocket, "%s", (char*)hstrerror(h_errno));
#else
        rb_raise(rb_eSocket, "host not found");
#endif
    }
    ary = rb_ary_new();
    rb_ary_push(ary, rb_str_new2(h->h_name));
    names = rb_ary_new();
    rb_ary_push(ary, names);
    if (h->h_aliases != NULL) {
        for (pch = h->h_aliases; *pch; pch++) {
            rb_ary_push(names, rb_str_new2(*pch));
        }
    }
    rb_ary_push(ary, INT2NUM(h->h_addrtype));
#ifdef h_addr
    for (pch = h->h_addr_list; *pch; pch++) {
        rb_ary_push(ary, rb_str_new(*pch, h->h_length));
    }
#else
    rb_ary_push(ary, rb_str_new(h->h_addr, h->h_length));
#endif

    return ary;
}
gethostbyname(hostname) → [official_hostname, alias_hostnames, address_family, *address_list] click to toggle source

Obtains the host information for hostname.

p Socket.gethostbyname("hal") #=> ["localhost", ["hal"], 2, "\x7F\x00\x00\x01"]

static VALUE
sock_s_gethostbyname(VALUE obj, VALUE host)
{
    rb_secure(3);
    return rsock_make_hostent(host, rsock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), sock_sockaddr);
}
gethostname → hostname click to toggle source

Returns the hostname.

p Socket.gethostname #=> "hal"

Note that it is not guaranteed to be able to convert to IP address using gethostbyname, getaddrinfo, etc. If you need local IP address, use ::ip_address_list.

static VALUE
sock_gethostname(VALUE obj)
{
#ifndef HOST_NAME_MAX
#  define HOST_NAME_MAX 1024
#endif
    char buf[HOST_NAME_MAX+1];

    rb_secure(3);
    if (gethostname(buf, (int)sizeof buf - 1) < 0)
        rb_sys_fail("gethostname");

    buf[sizeof buf - 1] = '\0';
    return rb_str_new2(buf);
}
getnameinfo(sockaddr [, flags]) → [hostname, servicename] click to toggle source

Obtains name information for sockaddr.

sockaddr should be one of follows.

  • packed sockaddr string such as ::sockaddr_in(80, “127.0.0.1”)

  • 3-elements array such as [“AF_INET”, 80, “127.0.0.1”]

  • 4-elements array such as [“AF_INET”, 80, ignored, “127.0.0.1”]

flags should be bitwise OR of Socket::NI_* constants.

Note: The last form is compatible with IPSocket#addr and IPSocket#peeraddr.

Socket.getnameinfo(Socket.sockaddr_in(80, "127.0.0.1"))       #=> ["localhost", "www"]
Socket.getnameinfo(["AF_INET", 80, "127.0.0.1"])              #=> ["localhost", "www"]
Socket.getnameinfo(["AF_INET", 80, "localhost", "127.0.0.1"]) #=> ["localhost", "www"]

If Addrinfo object is preferred, use Addrinfo#getnameinfo.

static VALUE
sock_s_getnameinfo(int argc, VALUE *argv)
{
    VALUE sa, af = Qnil, host = Qnil, port = Qnil, flags, tmp;
    char *hptr, *pptr;
    char hbuf[1024], pbuf[1024];
    int fl;
    struct addrinfo hints, *res = NULL, *r;
    int error, saved_errno;
    struct sockaddr_storage ss;
    struct sockaddr *sap;
    socklen_t salen;

    sa = flags = Qnil;
    rb_scan_args(argc, argv, "11", &sa, &flags);

    fl = 0;
    if (!NIL_P(flags)) {
        fl = NUM2INT(flags);
    }
    tmp = rb_check_sockaddr_string_type(sa);
    if (!NIL_P(tmp)) {
        sa = tmp;
        if (sizeof(ss) < (size_t)RSTRING_LEN(sa)) {
            rb_raise(rb_eTypeError, "sockaddr length too big");
        }
        memcpy(&ss, RSTRING_PTR(sa), RSTRING_LEN(sa));
        if ((size_t)RSTRING_LEN(sa) != SS_LEN(&ss)) {
            rb_raise(rb_eTypeError, "sockaddr size differs - should not happen");
        }
        sap = (struct sockaddr*)&ss;
        salen = RSTRING_LEN(sa);
        goto call_nameinfo;
    }
    tmp = rb_check_array_type(sa);
    if (!NIL_P(tmp)) {
        sa = tmp;
        MEMZERO(&hints, struct addrinfo, 1);
        if (RARRAY_LEN(sa) == 3) {
            af = RARRAY_PTR(sa)[0];
            port = RARRAY_PTR(sa)[1];
            host = RARRAY_PTR(sa)[2];
        }
        else if (RARRAY_LEN(sa) >= 4) {
            af = RARRAY_PTR(sa)[0];
            port = RARRAY_PTR(sa)[1];
            host = RARRAY_PTR(sa)[3];
            if (NIL_P(host)) {
                host = RARRAY_PTR(sa)[2];
            }
            else {
                /*
                 * 4th element holds numeric form, don't resolve.
                 * see rsock_ipaddr().
                 */
#ifdef AI_NUMERICHOST /* AIX 4.3.3 doesn't have AI_NUMERICHOST. */
                hints.ai_flags |= AI_NUMERICHOST;
#endif
            }
        }
        else {
            rb_raise(rb_eArgError, "array size should be 3 or 4, %ld given",
                     RARRAY_LEN(sa));
        }
        /* host */
        if (NIL_P(host)) {
            hptr = NULL;
        }
        else {
            strncpy(hbuf, StringValuePtr(host), sizeof(hbuf));
            hbuf[sizeof(hbuf) - 1] = '\0';
            hptr = hbuf;
        }
        /* port */
        if (NIL_P(port)) {
            strcpy(pbuf, "0");
            pptr = NULL;
        }
        else if (FIXNUM_P(port)) {
            snprintf(pbuf, sizeof(pbuf), "%ld", NUM2LONG(port));
            pptr = pbuf;
        }
        else {
            strncpy(pbuf, StringValuePtr(port), sizeof(pbuf));
            pbuf[sizeof(pbuf) - 1] = '\0';
            pptr = pbuf;
        }
        hints.ai_socktype = (fl & NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;
        /* af */
        hints.ai_family = NIL_P(af) ? PF_UNSPEC : rsock_family_arg(af);
        error = rb_getaddrinfo(hptr, pptr, &hints, &res);
        if (error) goto error_exit_addr;
        sap = res->ai_addr;
        salen = res->ai_addrlen;
    }
    else {
        rb_raise(rb_eTypeError, "expecting String or Array");
    }

  call_nameinfo:
    error = rb_getnameinfo(sap, salen, hbuf, sizeof(hbuf),
                           pbuf, sizeof(pbuf), fl);
    if (error) goto error_exit_name;
    if (res) {
        for (r = res->ai_next; r; r = r->ai_next) {
            char hbuf2[1024], pbuf2[1024];

            sap = r->ai_addr;
            salen = r->ai_addrlen;
            error = rb_getnameinfo(sap, salen, hbuf2, sizeof(hbuf2),
                                   pbuf2, sizeof(pbuf2), fl);
            if (error) goto error_exit_name;
            if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) {
                freeaddrinfo(res);
                rb_raise(rb_eSocket, "sockaddr resolved to multiple nodename");
            }
        }
        freeaddrinfo(res);
    }
    return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf));

  error_exit_addr:
    saved_errno = errno;
    if (res) freeaddrinfo(res);
    errno = saved_errno;
    rsock_raise_socket_error("getaddrinfo", error);

  error_exit_name:
    saved_errno = errno;
    if (res) freeaddrinfo(res);
    errno = saved_errno;
    rsock_raise_socket_error("getnameinfo", error);

    UNREACHABLE;
}
getservbyname(service_name) → port_number click to toggle source
getservbyname(service_name, protocol_name) → port_number

Obtains the port number for service_name.

If protocol_name is not given, “tcp” is assumed.

Socket.getservbyname("smtp")          #=> 25
Socket.getservbyname("shell")         #=> 514
Socket.getservbyname("syslog", "udp") #=> 514

static VALUE
sock_s_getservbyname(int argc, VALUE *argv)
{
    VALUE service, proto;
    struct servent *sp;
    long port;
    const char *servicename, *protoname = "tcp";

    rb_scan_args(argc, argv, "11", &service, &proto);
    StringValue(service);
    if (!NIL_P(proto)) StringValue(proto);
    servicename = StringValueCStr(service);
    if (!NIL_P(proto)) protoname = StringValueCStr(proto);
    sp = getservbyname(servicename, protoname);
    if (sp) {
        port = ntohs(sp->s_port);
    }
    else {
        char *end;

        port = STRTOUL(servicename, &end, 0);
        if (*end != '\0') {
            rb_raise(rb_eSocket, "no such service %s/%s", servicename, protoname);
        }
    }
    return INT2FIX(port);
}
getservbyport(port [, protocol_name]) → service click to toggle source

Obtains the port number for port.

If protocol_name is not given, “tcp” is assumed.

Socket.getservbyport(80)         #=> "www"
Socket.getservbyport(514, "tcp") #=> "shell"
Socket.getservbyport(514, "udp") #=> "syslog"

static VALUE
sock_s_getservbyport(int argc, VALUE *argv)
{
    VALUE port, proto;
    struct servent *sp;
    long portnum;
    const char *protoname = "tcp";

    rb_scan_args(argc, argv, "11", &port, &proto);
    portnum = NUM2LONG(port);
    if (portnum != (uint16_t)portnum) {
        const char *s = portnum > 0 ? "big" : "small";
        rb_raise(rb_eRangeError, "integer %ld too %s to convert into `int16_t'", portnum, s);
    }
    if (!NIL_P(proto)) protoname = StringValueCStr(proto);

    sp = getservbyport((int)htons((uint16_t)portnum), protoname);
    if (!sp) {
        rb_raise(rb_eSocket, "no such service for port %d/%s", (int)portnum, protoname);
    }
    return rb_tainted_str_new2(sp->s_name);
}
ip_address_list → array click to toggle source

Returns local IP addresses as an array.

The array contains Addrinfo objects.

pp Socket.ip_address_list
#=> [#<Addrinfo: 127.0.0.1>,
     #<Addrinfo: 192.168.0.128>,
     #<Addrinfo: ::1>,
     ...]

static VALUE
socket_s_ip_address_list(VALUE self)
{
#if defined(HAVE_GETIFADDRS)
    struct ifaddrs *ifp = NULL;
    struct ifaddrs *p;
    int ret;
    VALUE list;

    ret = getifaddrs(&ifp);
    if (ret == -1) {
        rb_sys_fail("getifaddrs");
    }

    list = rb_ary_new();
    for (p = ifp; p; p = p->ifa_next) {
        if (p->ifa_addr != NULL && IS_IP_FAMILY(p->ifa_addr->sa_family)) {
            rb_ary_push(list, sockaddr_obj(p->ifa_addr));
        }
    }

    freeifaddrs(ifp);

    return list;
#elif defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)
    /* Solaris if_tcp(7P) */
    /* HP-UX has SIOCGLIFCONF too.  But it uses different struct */
    int fd = -1;
    int ret;
    struct lifnum ln;
    struct lifconf lc;
    char *reason = NULL;
    int save_errno;
    int i;
    VALUE list = Qnil;

    lc.lifc_buf = NULL;

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd == -1)
        rb_sys_fail("socket");

    memset(&ln, 0, sizeof(ln));
    ln.lifn_family = AF_UNSPEC;

    ret = ioctl(fd, SIOCGLIFNUM, &ln);
    if (ret == -1) {
        reason = "SIOCGLIFNUM";
        goto finish;
    }

    memset(&lc, 0, sizeof(lc));
    lc.lifc_family = AF_UNSPEC;
    lc.lifc_flags = 0;
    lc.lifc_len = sizeof(struct lifreq) * ln.lifn_count;
    lc.lifc_req = xmalloc(lc.lifc_len);

    ret = ioctl(fd, SIOCGLIFCONF, &lc);
    if (ret == -1) {
        reason = "SIOCGLIFCONF";
        goto finish;
    }

    list = rb_ary_new();
    for (i = 0; i < ln.lifn_count; i++) {
        struct lifreq *req = &lc.lifc_req[i];
        if (IS_IP_FAMILY(req->lifr_addr.ss_family)) {
            if (req->lifr_addr.ss_family == AF_INET6 &&
                IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_addr) &&
                ((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id == 0) {
                struct lifreq req2;
                memcpy(req2.lifr_name, req->lifr_name, LIFNAMSIZ);
                ret = ioctl(fd, SIOCGLIFINDEX, &req2);
                if (ret == -1) {
                    reason = "SIOCGLIFINDEX";
                    goto finish;
                }
                ((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id = req2.lifr_index;
            }
            rb_ary_push(list, sockaddr_obj((struct sockaddr *)&req->lifr_addr));
        }
    }

  finish:
    save_errno = errno;
    if (lc.lifc_buf != NULL)
        xfree(lc.lifc_req);
    if (fd != -1)
        close(fd);
    errno = save_errno;

    if (reason)
        rb_sys_fail(reason);
    return list;

#elif defined(SIOCGIFCONF)
    int fd = -1;
    int ret;
#define EXTRA_SPACE (sizeof(struct ifconf) + sizeof(struct sockaddr_storage))
    char initbuf[4096+EXTRA_SPACE];
    char *buf = initbuf;
    int bufsize;
    struct ifconf conf;
    struct ifreq *req;
    VALUE list = Qnil;
    const char *reason = NULL;
    int save_errno;

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd == -1)
        rb_sys_fail("socket");

    bufsize = sizeof(initbuf);
    buf = initbuf;

  retry:
    conf.ifc_len = bufsize;
    conf.ifc_req = (struct ifreq *)buf;

    /* fprintf(stderr, "bufsize: %d\n", bufsize); */

    ret = ioctl(fd, SIOCGIFCONF, &conf);
    if (ret == -1) {
        reason = "SIOCGIFCONF";
        goto finish;
    }

    /* fprintf(stderr, "conf.ifc_len: %d\n", conf.ifc_len); */

    if (bufsize - EXTRA_SPACE < conf.ifc_len) {
        if (bufsize < conf.ifc_len) {
            /* NetBSD returns required size for all interfaces. */
            bufsize = conf.ifc_len + EXTRA_SPACE;
        }
        else {
            bufsize = bufsize << 1;
        }
        if (buf == initbuf)
            buf = NULL;
        buf = xrealloc(buf, bufsize);
        goto retry;
    }

    close(fd);
    fd = -1;

    list = rb_ary_new();
    req = conf.ifc_req;
    while ((char*)req < (char*)conf.ifc_req + conf.ifc_len) {
        struct sockaddr *addr = &req->ifr_addr;
        if (IS_IP_FAMILY(addr->sa_family)) {
            rb_ary_push(list, sockaddr_obj(addr));
        }
#ifdef HAVE_SA_LEN
# ifndef _SIZEOF_ADDR_IFREQ
#  define _SIZEOF_ADDR_IFREQ(r) \
          (sizeof(struct ifreq) + \
           (sizeof(struct sockaddr) < (r).ifr_addr.sa_len ? \
            (r).ifr_addr.sa_len - sizeof(struct sockaddr) : \
            0))
# endif
        req = (struct ifreq *)((char*)req + _SIZEOF_ADDR_IFREQ(*req));
#else
        req = (struct ifreq *)((char*)req + sizeof(struct ifreq));
#endif
    }

  finish:

    save_errno = errno;
    if (buf != initbuf)
        xfree(buf);
    if (fd != -1)
        close(fd);
    errno = save_errno;

    if (reason)
        rb_sys_fail(reason);
    return list;

#undef EXTRA_SPACE
#elif defined(_WIN32)
    typedef struct ip_adapter_unicast_address_st {
        unsigned LONG_LONG dummy0;
        struct ip_adapter_unicast_address_st *Next;
        struct {
            struct sockaddr *lpSockaddr;
            int iSockaddrLength;
        } Address;
        int dummy1;
        int dummy2;
        int dummy3;
        long dummy4;
        long dummy5;
        long dummy6;
    } ip_adapter_unicast_address_t;
    typedef struct ip_adapter_anycast_address_st {
        unsigned LONG_LONG dummy0;
        struct ip_adapter_anycast_address_st *Next;
        struct {
            struct sockaddr *lpSockaddr;
            int iSockaddrLength;
        } Address;
    } ip_adapter_anycast_address_t;
    typedef struct ip_adapter_addresses_st {
        unsigned LONG_LONG dummy0;
        struct ip_adapter_addresses_st *Next;
        void *dummy1;
        ip_adapter_unicast_address_t *FirstUnicastAddress;
        ip_adapter_anycast_address_t *FirstAnycastAddress;
        void *dummy2;
        void *dummy3;
        void *dummy4;
        void *dummy5;
        void *dummy6;
        BYTE dummy7[8];
        DWORD dummy8;
        DWORD dummy9;
        DWORD dummy10;
        DWORD IfType;
        int OperStatus;
        DWORD dummy12;
        DWORD dummy13[16];
        void *dummy14;
    } ip_adapter_addresses_t;
    typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG, ULONG, PVOID, ip_adapter_addresses_t *, PULONG);
    HMODULE h;
    GetAdaptersAddresses_t pGetAdaptersAddresses;
    ULONG len;
    DWORD ret;
    ip_adapter_addresses_t *adapters;
    VALUE list;

    h = LoadLibrary("iphlpapi.dll");
    if (!h)
        rb_notimplement();
    pGetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress(h, "GetAdaptersAddresses");
    if (!pGetAdaptersAddresses) {
        FreeLibrary(h);
        rb_notimplement();
    }

    ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &len);
    if (ret != ERROR_SUCCESS && ret != ERROR_BUFFER_OVERFLOW) {
        errno = rb_w32_map_errno(ret);
        FreeLibrary(h);
        rb_sys_fail("GetAdaptersAddresses");
    }
    adapters = (ip_adapter_addresses_t *)ALLOCA_N(BYTE, len);
    ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &len);
    if (ret != ERROR_SUCCESS) {
        errno = rb_w32_map_errno(ret);
        FreeLibrary(h);
        rb_sys_fail("GetAdaptersAddresses");
    }

    list = rb_ary_new();
    for (; adapters; adapters = adapters->Next) {
        ip_adapter_unicast_address_t *uni;
        ip_adapter_anycast_address_t *any;
        if (adapters->OperStatus != 1) /* 1 means IfOperStatusUp */
            continue;
        for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) {
#ifndef INET6
            if (uni->Address.lpSockaddr->sa_family == AF_INET)
#else
            if (IS_IP_FAMILY(uni->Address.lpSockaddr->sa_family))
#endif
                rb_ary_push(list, sockaddr_obj(uni->Address.lpSockaddr));
        }
        for (any = adapters->FirstAnycastAddress; any; any = any->Next) {
#ifndef INET6
            if (any->Address.lpSockaddr->sa_family == AF_INET)
#else
            if (IS_IP_FAMILY(any->Address.lpSockaddr->sa_family))
#endif
                rb_ary_push(list, sockaddr_obj(any->Address.lpSockaddr));
        }
    }

    FreeLibrary(h);
    return list;
#endif
}
new(domain, socktype [, protocol]) → socket click to toggle source

Creates a new socket object.

domain should be a communications domain such as: :INET, :INET6, :UNIX, etc.

socktype should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.

protocol is optional and should be a protocol defined in the domain. If protocol is not given, 0 is used internally.

Socket.new(:INET, :STREAM) # TCP socket
Socket.new(:INET, :DGRAM)  # UDP socket
Socket.new(:UNIX, :STREAM) # UNIX stream socket
Socket.new(:UNIX, :DGRAM)  # UNIX datagram socket
static VALUE
sock_initialize(int argc, VALUE *argv, VALUE sock)
{
    VALUE domain, type, protocol;
    int fd;
    int d, t;

    rb_scan_args(argc, argv, "21", &domain, &type, &protocol);
    if (NIL_P(protocol))
        protocol = INT2FIX(0);

    rb_secure(3);
    setup_domain_and_type(domain, &d, type, &t);
    fd = rsock_socket(d, t, NUM2INT(protocol));
    if (fd < 0) rb_sys_fail("socket(2)");

    return rsock_init_sock(sock, fd);
}
sockaddr_in(port, host) → sockaddr click to toggle source
pack_sockaddr_in(port, host) → sockaddr

Packs port and host as an AF_INET/AF_INET6 sockaddr string.

Socket.sockaddr_in(80, "127.0.0.1")
#=> "\x02\x00\x00P\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"

Socket.sockaddr_in(80, "::1")
#=> "\n\x00\x00P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"

static VALUE
sock_s_pack_sockaddr_in(VALUE self, VALUE port, VALUE host)
{
    struct addrinfo *res = rsock_addrinfo(host, port, 0, 0);
    VALUE addr = rb_str_new((char*)res->ai_addr, res->ai_addrlen);

    freeaddrinfo(res);
    OBJ_INFECT(addr, port);
    OBJ_INFECT(addr, host);

    return addr;
}
sockaddr_un(path) → sockaddr click to toggle source
pack_sockaddr_un(path) → sockaddr

Packs path as an AF_UNIX sockaddr string.

Socket.sockaddr_un("/tmp/sock") #=> "\x01\x00/tmp/sock\x00\x00..."

static VALUE
sock_s_pack_sockaddr_un(VALUE self, VALUE path)
{
    struct sockaddr_un sockaddr;
    VALUE addr;

    StringValue(path);
    MEMZERO(&sockaddr, struct sockaddr_un, 1);
    sockaddr.sun_family = AF_UNIX;
    if (sizeof(sockaddr.sun_path) < (size_t)RSTRING_LEN(path)) {
        rb_raise(rb_eArgError, "too long unix socket path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
            (size_t)RSTRING_LEN(path), sizeof(sockaddr.sun_path));
    }
    memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path));
    addr = rb_str_new((char*)&sockaddr, rsock_unix_sockaddr_len(path));
    OBJ_INFECT(addr, path);

    return addr;
}
pair(domain, type, protocol) → [socket1, socket2] click to toggle source
socketpair(domain, type, protocol) → [socket1, socket2]

Creates a pair of sockets connected each other.

domain should be a communications domain such as: :INET, :INET6, :UNIX, etc.

socktype should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.

protocol should be a protocol defined in the domain, defaults to 0 for the domain.

s1, s2 = Socket.pair(:UNIX, :DGRAM, 0)
s1.send "a", 0
s1.send "b", 0
p s2.recv(10) #=> "a"
p s2.recv(10) #=> "b"

VALUE
rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass)
{
    VALUE domain, type, protocol;
    int d, t, p, sp[2];
    int ret;
    VALUE s1, s2, r;

    rb_scan_args(argc, argv, "21", &domain, &type, &protocol);
    if (NIL_P(protocol))
        protocol = INT2FIX(0);

    setup_domain_and_type(domain, &d, type, &t);
    p = NUM2INT(protocol);
    ret = rsock_socketpair(d, t, p, sp);
    if (ret < 0) {
        rb_sys_fail("socketpair(2)");
    }
    rb_fd_fix_cloexec(sp[0]);
    rb_fd_fix_cloexec(sp[1]);

    s1 = rsock_init_sock(rb_obj_alloc(klass), sp[0]);
    s2 = rsock_init_sock(rb_obj_alloc(klass), sp[1]);
    r = rb_assoc_new(s1, s2);
    if (rb_block_given_p()) {
        return rb_ensure(pair_yield, r, io_close, s1);
    }
    return r;
}
sockaddr_in(port, host) → sockaddr click to toggle source
pack_sockaddr_in(port, host) → sockaddr

Packs port and host as an AF_INET/AF_INET6 sockaddr string.

Socket.sockaddr_in(80, "127.0.0.1")
#=> "\x02\x00\x00P\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"

Socket.sockaddr_in(80, "::1")
#=> "\n\x00\x00P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"

static VALUE
sock_s_pack_sockaddr_in(VALUE self, VALUE port, VALUE host)
{
    struct addrinfo *res = rsock_addrinfo(host, port, 0, 0);
    VALUE addr = rb_str_new((char*)res->ai_addr, res->ai_addrlen);

    freeaddrinfo(res);
    OBJ_INFECT(addr, port);
    OBJ_INFECT(addr, host);

    return addr;
}
sockaddr_un(path) → sockaddr click to toggle source
pack_sockaddr_un(path) → sockaddr

Packs path as an AF_UNIX sockaddr string.

Socket.sockaddr_un("/tmp/sock") #=> "\x01\x00/tmp/sock\x00\x00..."

static VALUE
sock_s_pack_sockaddr_un(VALUE self, VALUE path)
{
    struct sockaddr_un sockaddr;
    VALUE addr;

    StringValue(path);
    MEMZERO(&sockaddr, struct sockaddr_un, 1);
    sockaddr.sun_family = AF_UNIX;
    if (sizeof(sockaddr.sun_path) < (size_t)RSTRING_LEN(path)) {
        rb_raise(rb_eArgError, "too long unix socket path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
            (size_t)RSTRING_LEN(path), sizeof(sockaddr.sun_path));
    }
    memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path));
    addr = rb_str_new((char*)&sockaddr, rsock_unix_sockaddr_len(path));
    OBJ_INFECT(addr, path);

    return addr;
}
pair(domain, type, protocol) → [socket1, socket2] click to toggle source
socketpair(domain, type, protocol) → [socket1, socket2]

Creates a pair of sockets connected each other.

domain should be a communications domain such as: :INET, :INET6, :UNIX, etc.

socktype should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.

protocol should be a protocol defined in the domain, defaults to 0 for the domain.

s1, s2 = Socket.pair(:UNIX, :DGRAM, 0)
s1.send "a", 0
s1.send "b", 0
p s2.recv(10) #=> "a"
p s2.recv(10) #=> "b"

VALUE
rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass)
{
    VALUE domain, type, protocol;
    int d, t, p, sp[2];
    int ret;
    VALUE s1, s2, r;

    rb_scan_args(argc, argv, "21", &domain, &type, &protocol);
    if (NIL_P(protocol))
        protocol = INT2FIX(0);

    setup_domain_and_type(domain, &d, type, &t);
    p = NUM2INT(protocol);
    ret = rsock_socketpair(d, t, p, sp);
    if (ret < 0) {
        rb_sys_fail("socketpair(2)");
    }
    rb_fd_fix_cloexec(sp[0]);
    rb_fd_fix_cloexec(sp[1]);

    s1 = rsock_init_sock(rb_obj_alloc(klass), sp[0]);
    s2 = rsock_init_sock(rb_obj_alloc(klass), sp[1]);
    r = rb_assoc_new(s1, s2);
    if (rb_block_given_p()) {
        return rb_ensure(pair_yield, r, io_close, s1);
    }
    return r;
}
tcp(host, port, local_host=nil, local_port=nil, [opts]) {|socket| ... } click to toggle source
tcp(host, port, local_host=nil, local_port=nil, [opts])

creates a new socket object connected to host:port using TCP/IP.

If local_host:local_port is given, the socket is bound to it.

The optional last argument opts is options represented by a hash. opts may have following options:

:connect_timeout

specify the timeout in seconds.

If a block is given, the block is called with the socket. The value of the block is returned. The socket is closed when this method returns.

The optional last argument opts is options represented by a hash. opts may have following options:

:timeout

specify the timeout in seconds.

If no block is given, the socket is returned.

Socket.tcp("www.ruby-lang.org", 80) {|sock|
  sock.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  sock.close_write
  puts sock.read
}

# File ext/socket/lib/socket.rb, line 319
def self.tcp(host, port, *rest) # :yield: socket
  opts = Hash === rest.last ? rest.pop : {}
  raise ArgumentError, "wrong number of arguments (#{rest.length} for 2)" if 2 < rest.length
  local_host, local_port = rest
  last_error = nil
  ret = nil

  connect_timeout = opts[:connect_timeout]

  local_addr_list = nil
  if local_host != nil || local_port != nil
    local_addr_list = Addrinfo.getaddrinfo(local_host, local_port, nil, :STREAM, nil)
  end

  Addrinfo.foreach(host, port, nil, :STREAM) {|ai|
    if local_addr_list
      local_addr = local_addr_list.find {|local_ai| local_ai.afamily == ai.afamily }
      next if !local_addr
    else
      local_addr = nil
    end
    begin
      sock = local_addr ?
        ai.connect_from(local_addr, :timeout => connect_timeout) :
        ai.connect(:timeout => connect_timeout)
    rescue SystemCallError
      last_error = $!
      next
    end
    ret = sock
    break
  }
  if !ret
    if last_error
      raise last_error
    else
      raise SocketError, "no appropriate local address"
    end
  end
  if block_given?
    begin
      yield ret
    ensure
      ret.close if !ret.closed?
    end
  else
    ret
  end
end
tcp_server_loop(host=nil, port) { |socket, client_addrinfo| ... } click to toggle source

creates a TCP/IP server on port and calls the block for each connection accepted. The block is called with a socket and a client_address as an Addrinfo object.

If host is specified, it is used with port to determine the server addresses.

The socket is not closed when the block returns. So application should close it explicitly.

This method calls the block sequentially. It means that the next connection is not accepted until the block returns. So concurrent mechanism, thread for example, should be used to service multiple clients at a time.

Note that Addrinfo.getaddrinfo is used to determine the server socket addresses. When Addrinfo.getaddrinfo returns two or more addresses, IPv4 and IPv6 address for example, all of them are used. ::tcp_server_loop succeeds if one socket can be used at least.

# Sequential echo server.
# It services only one client at a time.
Socket.tcp_server_loop(16807) {|sock, client_addrinfo|
  begin
    IO.copy_stream(sock, sock)
  ensure
    sock.close
  end
}

# Threaded echo server
# It services multiple clients at a time.
# Note that it may accept connections too much.
Socket.tcp_server_loop(16807) {|sock, client_addrinfo|
  Thread.new {
    begin
      IO.copy_stream(sock, sock)
    ensure
      sock.close
    end
  }
}

# File ext/socket/lib/socket.rb, line 560
def self.tcp_server_loop(host=nil, port, &b) # :yield: socket, client_addrinfo
  tcp_server_sockets(host, port) {|sockets|
    accept_loop(sockets, &b)
  }
end
tcp_server_sockets(host=nil, port) { |sockets| ... } click to toggle source

creates TCP/IP server sockets for host and port. host is optional.

If no block given, it returns an array of listening sockets.

If a block is given, the block is called with the sockets. The value of the block is returned. The socket is closed when this method returns.

If port is 0, actual port number is chosen dynamically. However all sockets in the result has same port number.

# tcp_server_sockets returns two sockets.
sockets = Socket.tcp_server_sockets(1296)
p sockets #=> [#<Socket:fd 3>, #<Socket:fd 4>]

# The sockets contains IPv6 and IPv4 sockets.
sockets.each {|s| p s.local_address }
#=> #<Addrinfo: [::]:1296 TCP>
#   #<Addrinfo: 0.0.0.0:1296 TCP>

# IPv6 and IPv4 socket has same port number, 53114, even if it is chosen dynamically.
sockets = Socket.tcp_server_sockets(0)
sockets.each {|s| p s.local_address }
#=> #<Addrinfo: [::]:53114 TCP>
#   #<Addrinfo: 0.0.0.0:53114 TCP>

# The block is called with the sockets.
Socket.tcp_server_sockets(0) {|sockets|
  p sockets #=> [#<Socket:fd 3>, #<Socket:fd 4>]
}

# File ext/socket/lib/socket.rb, line 457
def self.tcp_server_sockets(host=nil, port)
  if port == 0
    sockets = tcp_server_sockets_port0(host)
  else
    last_error = nil
    sockets = []
    begin
      Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai|
        begin
          s = ai.listen
        rescue SystemCallError
          last_error = $!
          next
        end
        sockets << s
      }
      if sockets.empty?
        raise last_error
      end
    rescue Exception
      sockets.each {|s| s.close }
      raise
    end
  end
  if block_given?
    begin
      yield sockets
    ensure
      sockets.each {|s| s.close if !s.closed? }
    end
  else
    sockets
  end
end
udp_server_loop(port) {|msg, msg_src| ... } click to toggle source
udp_server_loop(host, port) {|msg, msg_src| ... }

creates a UDP/IP server on port and calls the block for each message arrived. The block is called with the message and its source information.

This method allocates sockets internally using port. If host is specified, it is used conjunction with port to determine the server addresses.

The msg is a string.

The msg_src is a Socket::UDPSource object. It is used for reply.

# UDP/IP echo server.
Socket.udp_server_loop(9261) {|msg, msg_src|
  msg_src.reply msg
}

# File ext/socket/lib/socket.rb, line 732
def self.udp_server_loop(host=nil, port, &b) # :yield: message, message_source
  udp_server_sockets(host, port) {|sockets|
    udp_server_loop_on(sockets, &b)
  }
end
udp_server_loop_on(sockets) {|msg, msg_src| ... } click to toggle source

Run UDP/IP server loop on the given sockets.

The return value of ::udp_server_sockets is appropriate for the argument.

It calls the block for each message received.

# File ext/socket/lib/socket.rb, line 705
def self.udp_server_loop_on(sockets, &b) # :yield: msg, msg_src
  loop {
    readable, _, _ = IO.select(sockets)
    udp_server_recv(readable, &b)
  }
end
udp_server_recv(sockets) {|msg, msg_src| ... } click to toggle source

Receive UDP/IP packets from the given sockets. For each packet received, the block is called.

The block receives msg and msg_src. msg is a string which is the payload of the received packet. msg_src is a Socket::UDPSource object which is used for reply.

::udp_server_loop can be implemented using this method as follows.

udp_server_sockets(host, port) {|sockets|
  loop {
    readable, _, _ = IO.select(sockets)
    udp_server_recv(readable) {|msg, msg_src| ... }
  }
}

# File ext/socket/lib/socket.rb, line 675
def self.udp_server_recv(sockets)
  sockets.each {|r|
    begin
      msg, sender_addrinfo, _, *controls = r.recvmsg_nonblock
    rescue IO::WaitReadable
      next
    end
    ai = r.local_address
    if ai.ipv6? and pktinfo = controls.find {|c| c.cmsg_is?(:IPV6, :PKTINFO) }
      ai = Addrinfo.udp(pktinfo.ipv6_pktinfo_addr.ip_address, ai.ip_port)
      yield msg, UDPSource.new(sender_addrinfo, ai) {|reply_msg|
        r.sendmsg reply_msg, 0, sender_addrinfo, pktinfo
      }
    else
      yield msg, UDPSource.new(sender_addrinfo, ai) {|reply_msg|
        r.send reply_msg, 0, sender_addrinfo
      }
    end
  }
end
udp_server_sockets([host, ] port) click to toggle source

Creates UDP/IP sockets for a UDP server.

If no block given, it returns an array of sockets.

If a block is given, the block is called with the sockets. The value of the block is returned. The sockets are closed when this method returns.

If port is zero, some port is chosen. But the chosen port is used for the all sockets.

# UDP/IP echo server
Socket.udp_server_sockets(0) {|sockets|
  p sockets.first.local_address.ip_port     #=> 32963
  Socket.udp_server_loop_on(sockets) {|msg, msg_src|
    msg_src.reply msg
  }
}

# File ext/socket/lib/socket.rb, line 588
def self.udp_server_sockets(host=nil, port)
  last_error = nil
  sockets = []

  ipv6_recvpktinfo = nil
  if defined? Socket::AncillaryData
    if defined? Socket::IPV6_RECVPKTINFO # RFC 3542
      ipv6_recvpktinfo = Socket::IPV6_RECVPKTINFO
    elsif defined? Socket::IPV6_PKTINFO # RFC 2292
      ipv6_recvpktinfo = Socket::IPV6_PKTINFO
    end
  end

  local_addrs = Socket.ip_address_list

  ip_list = []
  Addrinfo.foreach(host, port, nil, :DGRAM, nil, Socket::AI_PASSIVE) {|ai|
    if ai.ipv4? && ai.ip_address == "0.0.0.0"
      local_addrs.each {|a|
        next if !a.ipv4?
        ip_list << Addrinfo.new(a.to_sockaddr, :INET, :DGRAM, 0);
      }
    elsif ai.ipv6? && ai.ip_address == "::" && !ipv6_recvpktinfo
      local_addrs.each {|a|
        next if !a.ipv6?
        ip_list << Addrinfo.new(a.to_sockaddr, :INET6, :DGRAM, 0);
      }
    else
      ip_list << ai
    end
  }

  if port == 0
    sockets = ip_sockets_port0(ip_list, false)
  else
    ip_list.each {|ip|
      ai = Addrinfo.udp(ip.ip_address, port)
      begin
        s = ai.bind
      rescue SystemCallError
        last_error = $!
        next
      end
      sockets << s
    }
    if sockets.empty?
      raise last_error
    end
  end

  sockets.each {|s|
    ai = s.local_address
    if ipv6_recvpktinfo && ai.ipv6? && ai.ip_address == "::"
      s.setsockopt(:IPV6, ipv6_recvpktinfo, 1)
    end
  }

  if block_given?
    begin
      yield sockets
    ensure
      sockets.each {|s| s.close if !s.closed? } if sockets
    end
  else
    sockets
  end
end
unix(path) { |socket| ... } click to toggle source

creates a new socket connected to path using UNIX socket socket.

If a block is given, the block is called with the socket. The value of the block is returned. The socket is closed when this method returns.

If no block is given, the socket is returned.

# talk to /tmp/sock socket.
Socket.unix("/tmp/sock") {|sock|
  t = Thread.new { IO.copy_stream(sock, STDOUT) }
  IO.copy_stream(STDIN, sock)
  t.join
}

# File ext/socket/lib/socket.rb, line 782
def self.unix(path) # :yield: socket
  addr = Addrinfo.unix(path)
  sock = addr.connect
  if block_given?
    begin
      yield sock
    ensure
      sock.close if !sock.closed?
    end
  else
    sock
  end
end
unix_server_loop(path) { |socket, client_addrinfo| ... } click to toggle source

creates a UNIX socket server on path. It calls the block for each socket accepted.

If host is specified, it is used with port to determine the server ports.

The socket is not closed when the block returns. So application should close it.

This method deletes the socket file pointed by path at first if the file is a socket file and it is owned by the user of the application. This is safe only if the directory of path is not changed by a malicious user. So don't use /tmp/malicious-users-directory/socket. Note that /tmp/socket and /tmp/your-private-directory/socket is safe assuming that /tmp has sticky bit.

# Sequential echo server.
# It services only one client at a time.
Socket.unix_server_loop("/tmp/sock") {|sock, client_addrinfo|
  begin
    IO.copy_stream(sock, sock)
  ensure
    sock.close
  end
}

# File ext/socket/lib/socket.rb, line 869
def self.unix_server_loop(path, &b) # :yield: socket, client_addrinfo
  unix_server_socket(path) {|serv|
    accept_loop(serv, &b)
  }
end
unix_server_socket(path) { |s| ... } click to toggle source

creates a UNIX server socket on path

If no block given, it returns a listening socket.

If a block is given, it is called with the socket and the block value is returned. When the block exits, the socket is closed and the socket file is removed.

socket = Socket.unix_server_socket("/tmp/s")
p socket                  #=> #<Socket:fd 3>
p socket.local_address    #=> #<Addrinfo: /tmp/s SOCK_STREAM>

Socket.unix_server_socket("/tmp/sock") {|s|
  p s                     #=> #<Socket:fd 3>
  p s.local_address       #=> # #<Addrinfo: /tmp/sock SOCK_STREAM>
}

# File ext/socket/lib/socket.rb, line 812
def self.unix_server_socket(path)
  if !unix_socket_abstract_name?(path)
    begin
      st = File.lstat(path)
    rescue Errno::ENOENT
    end
    if st && st.socket? && st.owned?
      File.unlink path
    end
  end
  s = Addrinfo.unix(path).listen
  if block_given?
    begin
      yield s
    ensure
      s.close if !s.closed?
      if !unix_socket_abstract_name?(path)
        File.unlink path
      end
    end
  else
    s
  end
end
unpack_sockaddr_in(sockaddr) → [port, ip_address] click to toggle source

Unpacks sockaddr into port and ip_address.

sockaddr should be a string or an addrinfo for AF_INET/AF_INET6.

sockaddr = Socket.sockaddr_in(80, "127.0.0.1")
p sockaddr #=> "\x02\x00\x00P\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
p Socket.unpack_sockaddr_in(sockaddr) #=> [80, "127.0.0.1"]

static VALUE
sock_s_unpack_sockaddr_in(VALUE self, VALUE addr)
{
    struct sockaddr_in * sockaddr;
    VALUE host;

    sockaddr = (struct sockaddr_in*)SockAddrStringValuePtr(addr);
    if (RSTRING_LEN(addr) <
        (char*)&((struct sockaddr *)sockaddr)->sa_family +
        sizeof(((struct sockaddr *)sockaddr)->sa_family) -
        (char*)sockaddr)
        rb_raise(rb_eArgError, "too short sockaddr");
    if (((struct sockaddr *)sockaddr)->sa_family != AF_INET
#ifdef INET6
        && ((struct sockaddr *)sockaddr)->sa_family != AF_INET6
#endif
        ) {
#ifdef INET6
        rb_raise(rb_eArgError, "not an AF_INET/AF_INET6 sockaddr");
#else
        rb_raise(rb_eArgError, "not an AF_INET sockaddr");
#endif
    }
    host = rsock_make_ipaddr((struct sockaddr*)sockaddr, RSTRING_LEN(addr));
    OBJ_INFECT(host, addr);
    return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host);
}
unpack_sockaddr_un(sockaddr) → path click to toggle source

Unpacks sockaddr into path.

sockaddr should be a string or an addrinfo for AF_UNIX.

sockaddr = Socket.sockaddr_un("/tmp/sock")
p Socket.unpack_sockaddr_un(sockaddr) #=> "/tmp/sock"

static VALUE
sock_s_unpack_sockaddr_un(VALUE self, VALUE addr)
{
    struct sockaddr_un * sockaddr;
    VALUE path;

    sockaddr = (struct sockaddr_un*)SockAddrStringValuePtr(addr);
    if (RSTRING_LEN(addr) <
        (char*)&((struct sockaddr *)sockaddr)->sa_family +
        sizeof(((struct sockaddr *)sockaddr)->sa_family) -
        (char*)sockaddr)
        rb_raise(rb_eArgError, "too short sockaddr");
    if (((struct sockaddr *)sockaddr)->sa_family != AF_UNIX) {
        rb_raise(rb_eArgError, "not an AF_UNIX sockaddr");
    }
    if (sizeof(struct sockaddr_un) < (size_t)RSTRING_LEN(addr)) {
        rb_raise(rb_eTypeError, "too long sockaddr_un - %ld longer than %d",
                 RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un));
    }
    path = rsock_unixpath_str(sockaddr, RSTRING_LENINT(addr));
    OBJ_INFECT(path, addr);
    return path;
}

Public Instance Methods

accept → [client_socket, client_addrinfo] click to toggle source

Accepts a next connection. Returns a new Socket object and Addrinfo object.

serv = Socket.new(:INET, :STREAM, 0)
serv.listen(5)
c = Socket.new(:INET, :STREAM, 0)
c.connect(serv.connect_address)
p serv.accept #=> [#<Socket:fd 6>, #<Addrinfo: 127.0.0.1:48555 TCP>]

static VALUE
sock_accept(VALUE sock)
{
    rb_io_t *fptr;
    VALUE sock2;
    struct sockaddr_storage buf;
    socklen_t len = (socklen_t)sizeof buf;

    GetOpenFile(sock, fptr);
    sock2 = rsock_s_accept(rb_cSocket,fptr->fd,(struct sockaddr*)&buf,&len);

    return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, (struct sockaddr*)&buf, len));
}
accept_nonblock → [client_socket, client_addrinfo] click to toggle source

Accepts an incoming connection using accept(2) after O_NONBLOCK is set for the underlying file descriptor. It returns an array containing the accepted socket for the incoming connection, client_socket, and an Addrinfo, client_addrinfo.

Example

# In one script, start this first
require 'socket'
include Socket::Constants
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(2200, 'localhost')
socket.bind(sockaddr)
socket.listen(5)
begin # emulate blocking accept
  client_socket, client_addrinfo = socket.accept_nonblock
rescue IO::WaitReadable, Errno::EINTR
  IO.select([socket])
  retry
end
puts "The client said, '#{client_socket.readline.chomp}'"
client_socket.puts "Hello from script one!"
socket.close

# In another script, start this second
require 'socket'
include Socket::Constants
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(2200, 'localhost')
socket.connect(sockaddr)
socket.puts "Hello from script 2."
puts "The server said, '#{socket.readline.chomp}'"
socket.close

Refer to #accept for the exceptions that may be thrown if the call to #accept_nonblock fails.

#accept_nonblock may raise any error corresponding to accept(2) failure, including Errno::EWOULDBLOCK.

If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED or Errno::EPROTO, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.

See

  • #accept

static VALUE
sock_accept_nonblock(VALUE sock)
{
    rb_io_t *fptr;
    VALUE sock2;
    struct sockaddr_storage buf;
    socklen_t len = (socklen_t)sizeof buf;

    GetOpenFile(sock, fptr);
    sock2 = rsock_s_accept_nonblock(rb_cSocket, fptr, (struct sockaddr *)&buf, &len);
    return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, (struct sockaddr*)&buf, len));
}
bind(local_sockaddr) → 0 click to toggle source

Binds to the given local address.

Parameter

  • local_sockaddr - the struct sockaddr contained in a string or an Addrinfo object

Example

require 'socket'

# use Addrinfo
socket = Socket.new(:INET, :STREAM, 0)
socket.bind(Addrinfo.tcp("127.0.0.1", 2222))
p socket.local_address #=> #<Addrinfo: 127.0.0.1:2222 TCP>

# use struct sockaddr
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
socket.bind( sockaddr )

Unix-based Exceptions

On unix-based based systems the following system exceptions may be raised if the call to bind fails:

  • Errno::EACCES - the specified sockaddr is protected and the current user does not have permission to bind to it

  • Errno::EADDRINUSE - the specified sockaddr is already in use

  • Errno::EADDRNOTAVAIL - the specified sockaddr is not available from the local machine

  • Errno::EAFNOSUPPORT - the specified sockaddr is not a valid address for the family of the calling socket

  • Errno::EBADF - the sockaddr specified is not a valid file descriptor

  • Errno::EFAULT - the sockaddr argument cannot be accessed

  • Errno::EINVAL - the socket is already bound to an address, and the protocol does not support binding to the new sockaddr or the socket has been shut down.

  • Errno::EINVAL - the address length is not a valid length for the address family

  • Errno::ENAMETOOLONG - the pathname resolved had a length which exceeded PATH_MAX

  • Errno::ENOBUFS - no buffer space is available

  • Errno::ENOSR - there were insufficient STREAMS resources available to complete the operation

  • Errno::ENOTSOCK - the socket does not refer to a socket

  • Errno::EOPNOTSUPP - the socket type of the socket does not support binding to an address

On unix-based based systems if the address family of the calling socket is Socket::AF_UNIX the follow exceptions may be raised if the call to bind fails:

  • Errno::EACCES - search permission is denied for a component of the prefix path or write access to the socket is denied

  • Errno::EDESTADDRREQ - the sockaddr argument is a null pointer

  • Errno::EISDIR - same as Errno::EDESTADDRREQ

  • Errno::EIO - an i/o error occurred

  • Errno::ELOOP - too many symbolic links were encountered in translating the pathname in sockaddr

  • Errno::ENAMETOOLLONG - a component of a pathname exceeded NAME_MAX characters, or an entire pathname exceeded PATH_MAX characters

  • Errno::ENOENT - a component of the pathname does not name an existing file or the pathname is an empty string

  • Errno::ENOTDIR - a component of the path prefix of the pathname in sockaddr is not a directory

  • Errno::EROFS - the name would reside on a read only filesystem

Windows Exceptions

On Windows systems the following system exceptions may be raised if the call to bind fails:

  • Errno::ENETDOWN– the network is down

  • Errno::EACCES - the attempt to connect the datagram socket to the broadcast address failed

  • Errno::EADDRINUSE - the socket's local address is already in use

  • Errno::EADDRNOTAVAIL - the specified address is not a valid address for this computer

  • Errno::EFAULT - the socket's internal address or address length parameter is too small or is not a valid part of the user space addressed

  • Errno::EINVAL - the socket is already bound to an address

  • Errno::ENOBUFS - no buffer space is available

  • Errno::ENOTSOCK - the socket argument does not refer to a socket

See

  • bind manual pages on unix-based systems

  • bind function in Microsoft's Winsock functions reference

static VALUE
sock_bind(VALUE sock, VALUE addr)
{
    rb_io_t *fptr;

    SockAddrStringValue(addr);
    GetOpenFile(sock, fptr);
    if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr)) < 0)
        rb_sys_fail("bind(2)");

    return INT2FIX(0);
}
connect(remote_sockaddr) → 0 click to toggle source

Requests a connection to be made on the given remote_sockaddr. Returns 0 if successful, otherwise an exception is raised.

Parameter

  • remote_sockaddr - the struct sockaddr contained in a string or Addrinfo object

Example:

# Pull down Google's web page
require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 80, 'www.google.com' )
socket.connect( sockaddr )
socket.write( "GET / HTTP/1.0\r\n\r\n" )
results = socket.read

Unix-based Exceptions

On unix-based systems the following system exceptions may be raised if the call to connect fails:

  • Errno::EACCES - search permission is denied for a component of the prefix path or write access to the socket is denied

  • Errno::EADDRINUSE - the sockaddr is already in use

  • Errno::EADDRNOTAVAIL - the specified sockaddr is not available from the local machine

  • Errno::EAFNOSUPPORT - the specified sockaddr is not a valid address for the address family of the specified socket

  • Errno::EALREADY - a connection is already in progress for the specified socket

  • Errno::EBADF - the socket is not a valid file descriptor

  • Errno::ECONNREFUSED - the target sockaddr was not listening for connections refused the connection request

  • Errno::ECONNRESET - the remote host reset the connection request

  • Errno::EFAULT - the sockaddr cannot be accessed

  • Errno::EHOSTUNREACH - the destination host cannot be reached (probably because the host is down or a remote router cannot reach it)

  • Errno::EINPROGRESS - the O_NONBLOCK is set for the socket and the connection cannot be immediately established; the connection will be established asynchronously

  • Errno::EINTR - the attempt to establish the connection was interrupted by delivery of a signal that was caught; the connection will be established asynchronously

  • Errno::EISCONN - the specified socket is already connected

  • Errno::EINVAL - the address length used for the sockaddr is not a valid length for the address family or there is an invalid family in sockaddr

  • Errno::ENAMETOOLONG - the pathname resolved had a length which exceeded PATH_MAX

  • Errno::ENETDOWN - the local interface used to reach the destination is down

  • Errno::ENETUNREACH - no route to the network is present

  • Errno::ENOBUFS - no buffer space is available

  • Errno::ENOSR - there were insufficient STREAMS resources available to complete the operation

  • Errno::ENOTSOCK - the socket argument does not refer to a socket

  • Errno::EOPNOTSUPP - the calling socket is listening and cannot be connected

  • Errno::EPROTOTYPE - the sockaddr has a different type than the socket bound to the specified peer address

  • Errno::ETIMEDOUT - the attempt to connect time out before a connection was made.

On unix-based systems if the address family of the calling socket is AF_UNIX the follow exceptions may be raised if the call to connect fails:

  • Errno::EIO - an i/o error occurred while reading from or writing to the file system

  • Errno::ELOOP - too many symbolic links were encountered in translating the pathname in sockaddr

  • Errno::ENAMETOOLLONG - a component of a pathname exceeded NAME_MAX characters, or an entire pathname exceeded PATH_MAX characters

  • Errno::ENOENT - a component of the pathname does not name an existing file or the pathname is an empty string

  • Errno::ENOTDIR - a component of the path prefix of the pathname in sockaddr is not a directory

Windows Exceptions

On Windows systems the following system exceptions may be raised if the call to connect fails:

  • Errno::ENETDOWN - the network is down

  • Errno::EADDRINUSE - the socket's local address is already in use

  • Errno::EINTR - the socket was cancelled

  • Errno::EINPROGRESS - a blocking socket is in progress or the service provider is still processing a callback function. Or a nonblocking connect call is in progress on the socket.

  • Errno::EALREADY - see Errno::EINVAL

  • Errno::EADDRNOTAVAIL - the remote address is not a valid address, such as ADDR_ANY TODO check ADDRANY TO INADDR_ANY

  • Errno::EAFNOSUPPORT - addresses in the specified family cannot be used with with this socket

  • Errno::ECONNREFUSED - the target sockaddr was not listening for connections refused the connection request

  • Errno::EFAULT - the socket's internal address or address length parameter is too small or is not a valid part of the user space address

  • Errno::EINVAL - the socket is a listening socket

  • Errno::EISCONN - the socket is already connected

  • Errno::ENETUNREACH - the network cannot be reached from this host at this time

  • Errno::EHOSTUNREACH - no route to the network is present

  • Errno::ENOBUFS - no buffer space is available

  • Errno::ENOTSOCK - the socket argument does not refer to a socket

  • Errno::ETIMEDOUT - the attempt to connect time out before a connection was made.

  • Errno::EWOULDBLOCK - the socket is marked as nonblocking and the connection cannot be completed immediately

  • Errno::EACCES - the attempt to connect the datagram socket to the broadcast address failed

See

  • connect manual pages on unix-based systems

  • connect function in Microsoft's Winsock functions reference

static VALUE
sock_connect(VALUE sock, VALUE addr)
{
    rb_io_t *fptr;
    int fd, n;

    SockAddrStringValue(addr);
    addr = rb_str_new4(addr);
    GetOpenFile(sock, fptr);
    fd = fptr->fd;
    n = rsock_connect(fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr), 0);
    if (n < 0) {
        rb_sys_fail("connect(2)");
    }

    return INT2FIX(n);
}
connect_nonblock(remote_sockaddr) → 0 click to toggle source

Requests a connection to be made on the given remote_sockaddr after O_NONBLOCK is set for the underlying file descriptor. Returns 0 if successful, otherwise an exception is raised.

Parameter

  • remote_sockaddr - the struct sockaddr contained in a string or Addrinfo object

Example:

# Pull down Google's web page
require 'socket'
include Socket::Constants
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(80, 'www.google.com')
begin # emulate blocking connect
  socket.connect_nonblock(sockaddr)
rescue IO::WaitWritable
  IO.select(nil, [socket]) # wait 3-way handshake completion
  begin
    socket.connect_nonblock(sockaddr) # check connection failure
  rescue Errno::EISCONN
  end
end
socket.write("GET / HTTP/1.0\r\n\r\n")
results = socket.read

Refer to #connect for the exceptions that may be thrown if the call to #connect_nonblock fails.

#connect_nonblock may raise any error corresponding to connect(2) failure, including Errno::EINPROGRESS.

If the exception is Errno::EINPROGRESS, it is extended by IO::WaitWritable. So IO::WaitWritable can be used to rescue the exceptions for retrying connect_nonblock.

See

  • #connect

static VALUE
sock_connect_nonblock(VALUE sock, VALUE addr)
{
    rb_io_t *fptr;
    int n;

    SockAddrStringValue(addr);
    addr = rb_str_new4(addr);
    GetOpenFile(sock, fptr);
    rb_io_set_nonblock(fptr);
    n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr));
    if (n < 0) {
        if (errno == EINPROGRESS)
            rb_mod_sys_fail(rb_mWaitWritable, "connect(2) would block");
        rb_sys_fail("connect(2)");
    }

    return INT2FIX(n);
}
ipv6only!() click to toggle source

enable the socket option IPV6_V6ONLY if IPV6_V6ONLY is available.

# File ext/socket/lib/socket.rb, line 282
def ipv6only!
  if defined? Socket::IPV6_V6ONLY
    self.setsockopt(:IPV6, :V6ONLY, 1)
  end
end
listen( int ) → 0 click to toggle source

Listens for connections, using the specified int as the backlog. A call to listen only applies if the socket is of type SOCK_STREAM or SOCK_SEQPACKET.

Parameter

  • backlog - the maximum length of the queue for pending connections.

Example 1

require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
socket.bind( sockaddr )
socket.listen( 5 )

Example 2 (listening on an arbitrary port, unix-based systems only):

require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
socket.listen( 1 )

Unix-based Exceptions

On unix based systems the above will work because a new sockaddr struct is created on the address ADDR_ANY, for an arbitrary port number as handed off by the kernel. It will not work on Windows, because Windows requires that the socket is bound by calling bind before it can listen.

If the backlog amount exceeds the implementation-dependent maximum queue length, the implementation's maximum queue length will be used.

On unix-based based systems the following system exceptions may be raised if the call to listen fails:

  • Errno::EBADF - the socket argument is not a valid file descriptor

  • Errno::EDESTADDRREQ - the socket is not bound to a local address, and the protocol does not support listening on an unbound socket

  • Errno::EINVAL - the socket is already connected

  • Errno::ENOTSOCK - the socket argument does not refer to a socket

  • Errno::EOPNOTSUPP - the socket protocol does not support listen

  • Errno::EACCES - the calling process does not have appropriate privileges

  • Errno::EINVAL - the socket has been shut down

  • Errno::ENOBUFS - insufficient resources are available in the system to complete the call

Windows Exceptions

On Windows systems the following system exceptions may be raised if the call to listen fails:

  • Errno::ENETDOWN - the network is down

  • Errno::EADDRINUSE - the socket's local address is already in use. This usually occurs during the execution of bind but could be delayed if the call to bind was to a partially wildcard address (involving ADDR_ANY) and if a specific address needs to be committed at the time of the call to listen

  • Errno::EINPROGRESS - a Windows Sockets 1.1 call is in progress or the service provider is still processing a callback function

  • Errno::EINVAL - the socket has not been bound with a call to bind.

  • Errno::EISCONN - the socket is already connected

  • Errno::EMFILE - no more socket descriptors are available

  • Errno::ENOBUFS - no buffer space is available

  • Errno::ENOTSOC - socket is not a socket

  • Errno::EOPNOTSUPP - the referenced socket is not a type that supports the listen method

See

  • listen manual pages on unix-based systems

  • listen function in Microsoft's Winsock functions reference

VALUE
rsock_sock_listen(VALUE sock, VALUE log)
{
    rb_io_t *fptr;
    int backlog;

    rb_secure(4);
    backlog = NUM2INT(log);
    GetOpenFile(sock, fptr);
    if (listen(fptr->fd, backlog) < 0)
        rb_sys_fail("listen(2)");

    return INT2FIX(0);
}
recvfrom(maxlen) → [mesg, sender_addrinfo] click to toggle source
recvfrom(maxlen, flags) → [mesg, sender_addrinfo]

Receives up to maxlen bytes from socket. flags is zero or more of the MSG_ options. The first element of the results, mesg, is the data received. The second element, sender_addrinfo, contains protocol-specific address information of the sender.

Parameters

  • maxlen - the maximum number of bytes to receive from the socket

  • flags - zero or more of the MSG_ options

Example

# In one file, start this first
require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
socket.bind( sockaddr )
socket.listen( 5 )
client, client_addrinfo = socket.accept
data = client.recvfrom( 20 )[0].chomp
puts "I only received 20 bytes '#{data}'"
sleep 1
socket.close

# In another file, start this second
require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
socket.connect( sockaddr )
socket.puts "Watch this get cut short!"
socket.close

Unix-based Exceptions

On unix-based based systems the following system exceptions may be raised if the call to recvfrom fails:

  • Errno::EAGAIN - the socket file descriptor is marked as O_NONBLOCK and no data is waiting to be received; or MSG_OOB is set and no out-of-band data is available and either the socket file descriptor is marked as O_NONBLOCK or the socket does not support blocking to wait for out-of-band-data

  • Errno::EWOULDBLOCK - see Errno::EAGAIN

  • Errno::EBADF - the socket is not a valid file descriptor

  • Errno::ECONNRESET - a connection was forcibly closed by a peer

  • Errno::EFAULT - the socket's internal buffer, address or address length cannot be accessed or written

  • Errno::EINTR - a signal interrupted recvfrom before any data was available

  • Errno::EINVAL - the MSG_OOB flag is set and no out-of-band data is available

  • Errno::EIO - an i/o error occurred while reading from or writing to the filesystem

  • Errno::ENOBUFS - insufficient resources were available in the system to perform the operation

  • Errno::ENOMEM - insufficient memory was available to fulfill the request

  • Errno::ENOSR - there were insufficient STREAMS resources available to complete the operation

  • Errno::ENOTCONN - a receive is attempted on a connection-mode socket that is not connected

  • Errno::ENOTSOCK - the socket does not refer to a socket

  • Errno::EOPNOTSUPP - the specified flags are not supported for this socket type

  • Errno::ETIMEDOUT - the connection timed out during connection establishment or due to a transmission timeout on an active connection

Windows Exceptions

On Windows systems the following system exceptions may be raised if the call to recvfrom fails:

  • Errno::ENETDOWN - the network is down

  • Errno::EFAULT - the internal buffer and from parameters on socket are not part of the user address space, or the internal fromlen parameter is too small to accommodate the peer address

  • Errno::EINTR - the (blocking) call was cancelled by an internal call to the WinSock function WSACancelBlockingCall

  • Errno::EINPROGRESS - a blocking Windows Sockets 1.1 call is in progress or the service provider is still processing a callback function

  • Errno::EINVAL - socket has not been bound with a call to bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, or (for byte stream-style sockets only) the internal len parameter on socket was zero or negative

  • Errno::EISCONN - socket is already connected. The call to recvfrom is not permitted with a connected socket on a socket that is connection oriented or connectionless.

  • Errno::ENETRESET - the connection has been broken due to the keep-alive activity detecting a failure while the operation was in progress.

  • Errno::EOPNOTSUPP - MSG_OOB was specified, but socket is not stream-style such as type SOCK_STREAM. OOB data is not supported in the communication domain associated with socket, or socket is unidirectional and supports only send operations

  • Errno::ESHUTDOWN - socket has been shutdown. It is not possible to call recvfrom on a socket after shutdown has been invoked.

  • Errno::EWOULDBLOCK - socket is marked as nonblocking and a call to recvfrom would block.

  • Errno::EMSGSIZE - the message was too large to fit into the specified buffer and was truncated.

  • Errno::ETIMEDOUT - the connection has been dropped, because of a network failure or because the system on the other end went down without notice

  • Errno::ECONNRESET - the virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket; it is no longer usable. On a UDP-datagram socket this error indicates a previous send operation resulted in an ICMP Port Unreachable message.

static VALUE
sock_recvfrom(int argc, VALUE *argv, VALUE sock)
{
    return rsock_s_recvfrom(sock, argc, argv, RECV_SOCKET);
}
recvfrom_nonblock(maxlen) → [mesg, sender_addrinfo] click to toggle source
recvfrom_nonblock(maxlen, flags) → [mesg, sender_addrinfo]

Receives up to maxlen bytes from socket using recvfrom(2) after O_NONBLOCK is set for the underlying file descriptor. flags is zero or more of the MSG_ options. The first element of the results, mesg, is the data received. The second element, sender_addrinfo, contains protocol-specific address information of the sender.

When recvfrom(2) returns 0, #recvfrom_nonblock returns an empty string as data. The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.

Parameters

  • maxlen - the maximum number of bytes to receive from the socket

  • flags - zero or more of the MSG_ options

Example

# In one file, start this first
require 'socket'
include Socket::Constants
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(2200, 'localhost')
socket.bind(sockaddr)
socket.listen(5)
client, client_addrinfo = socket.accept
begin # emulate blocking recvfrom
  pair = client.recvfrom_nonblock(20)
rescue IO::WaitReadable
  IO.select([client])
  retry
end
data = pair[0].chomp
puts "I only received 20 bytes '#{data}'"
sleep 1
socket.close

# In another file, start this second
require 'socket'
include Socket::Constants
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(2200, 'localhost')
socket.connect(sockaddr)
socket.puts "Watch this get cut short!"
socket.close

Refer to #recvfrom for the exceptions that may be thrown if the call to #recvfrom_nonblock fails.

#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure, including Errno::EWOULDBLOCK.

If the exception is Errno::EWOULDBLOCK or Errno::AGAIN, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying recvfrom_nonblock.

See

  • #recvfrom

static VALUE
sock_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock)
{
    return rsock_s_recvfrom_nonblock(sock, argc, argv, RECV_SOCKET);
}
sysaccept → [client_socket_fd, client_addrinfo] click to toggle source

Accepts an incoming connection returning an array containing the (integer) file descriptor for the incoming connection, client_socket_fd, and an Addrinfo, client_addrinfo.

Example

# In one script, start this first
require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
socket.bind( sockaddr )
socket.listen( 5 )
client_fd, client_addrinfo = socket.sysaccept
client_socket = Socket.for_fd( client_fd )
puts "The client said, '#{client_socket.readline.chomp}'"
client_socket.puts "Hello from script one!"
socket.close

# In another script, start this second
require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
socket.connect( sockaddr )
socket.puts "Hello from script 2."
puts "The server said, '#{socket.readline.chomp}'"
socket.close

Refer to #accept for the exceptions that may be thrown if the call to sysaccept fails.

See

  • #accept

static VALUE
sock_sysaccept(VALUE sock)
{
    rb_io_t *fptr;
    VALUE sock2;
    struct sockaddr_storage buf;
    socklen_t len = (socklen_t)sizeof buf;

    GetOpenFile(sock, fptr);
    sock2 = rsock_s_accept(0,fptr->fd,(struct sockaddr*)&buf,&len);

    return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, (struct sockaddr*)&buf, len));
}


class Socket::AncillaryData - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Socket::AncillaryData

Socket::AncillaryData represents the ancillary data (control information) used by sendmsg and recvmsg system call. It contains socket family, control message (cmsg) level, cmsg type and cmsg data.

In Files

  • lib/ipaddr.rb

Parent

Object

Public Class Methods

Socket::AncillaryData.int(family, cmsg_level, cmsg_type, integer) → ancillarydata click to toggle source

Creates a new Socket::AncillaryData object which contains a int as data.

The size and endian is dependent on the host.

p Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, STDERR.fileno)
#=> #<Socket::AncillaryData: UNIX SOCKET RIGHTS 2>

static VALUE
ancillary_s_int(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE vtype, VALUE integer)
{
    int family = rsock_family_arg(vfamily);
    int level = rsock_level_arg(family, vlevel);
    int type = rsock_cmsg_type_arg(family, level, vtype);
    int i = NUM2INT(integer);
    return ancdata_new(family, level, type, rb_str_new((char*)&i, sizeof(i)));
}
Socket::AncillaryData.ip_pktinfo(addr, ifindex) → ancdata click to toggle source
Socket::AncillaryData.ip_pktinfo(addr, ifindex, spec_dst) → ancdata

Returns new ancillary data for IP_PKTINFO.

If spec_dst is not given, addr is used.

IP_PKTINFO is not standard.

Supported platform: GNU/Linux

addr = Addrinfo.ip("127.0.0.1")
ifindex = 0
spec_dst = Addrinfo.ip("127.0.0.1")
p Socket::AncillaryData.ip_pktinfo(addr, ifindex, spec_dst)
#=> #<Socket::AncillaryData: INET IP PKTINFO 127.0.0.1 ifindex:0 spec_dst:127.0.0.1>

static VALUE
ancillary_s_ip_pktinfo(int argc, VALUE *argv, VALUE self)
{
    VALUE v_addr, v_ifindex, v_spec_dst;
    unsigned int ifindex;
    struct sockaddr_in sa;
    struct in_pktinfo pktinfo;

    rb_scan_args(argc, argv, "21", &v_addr, &v_ifindex, &v_spec_dst);

    SockAddrStringValue(v_addr);
    ifindex = NUM2UINT(v_ifindex);
    if (NIL_P(v_spec_dst))
        v_spec_dst = v_addr;
    else
        SockAddrStringValue(v_spec_dst);

    memset(&pktinfo, 0, sizeof(pktinfo));

    memset(&sa, 0, sizeof(sa));
    if (RSTRING_LEN(v_addr) != sizeof(sa))
        rb_raise(rb_eArgError, "addr size different to AF_INET sockaddr");
    memcpy(&sa, RSTRING_PTR(v_addr), sizeof(sa));
    if (sa.sin_family != AF_INET)
        rb_raise(rb_eArgError, "addr is not AF_INET sockaddr");
    memcpy(&pktinfo.ipi_addr, &sa.sin_addr, sizeof(pktinfo.ipi_addr));

    pktinfo.ipi_ifindex = ifindex;

    memset(&sa, 0, sizeof(sa));
    if (RSTRING_LEN(v_spec_dst) != sizeof(sa))
        rb_raise(rb_eArgError, "spec_dat size different to AF_INET sockaddr");
    memcpy(&sa, RSTRING_PTR(v_spec_dst), sizeof(sa));
    if (sa.sin_family != AF_INET)
        rb_raise(rb_eArgError, "spec_dst is not AF_INET sockaddr");
    memcpy(&pktinfo.ipi_spec_dst, &sa.sin_addr, sizeof(pktinfo.ipi_spec_dst));

    return ancdata_new(AF_INET, IPPROTO_IP, IP_PKTINFO, rb_str_new((char *)&pktinfo, sizeof(pktinfo)));
}
Socket::AncillaryData.ipv6_pktinfo(addr, ifindex) → ancdata click to toggle source

Returns new ancillary data for IPV6_PKTINFO.

IPV6_PKTINFO is defined by RFC 3542.

addr = Addrinfo.ip("::1")
ifindex = 0
p Socket::AncillaryData.ipv6_pktinfo(addr, ifindex)
#=> #<Socket::AncillaryData: INET6 IPV6 PKTINFO ::1 ifindex:0>

static VALUE
ancillary_s_ipv6_pktinfo(VALUE self, VALUE v_addr, VALUE v_ifindex)
{
    unsigned int ifindex;
    struct sockaddr_in6 sa;
    struct in6_pktinfo pktinfo;

    SockAddrStringValue(v_addr);
    ifindex = NUM2UINT(v_ifindex);

    memset(&pktinfo, 0, sizeof(pktinfo));

    memset(&sa, 0, sizeof(sa));
    if (RSTRING_LEN(v_addr) != sizeof(sa))
        rb_raise(rb_eArgError, "addr size different to AF_INET6 sockaddr");
    memcpy(&sa, RSTRING_PTR(v_addr), sizeof(sa));
    if (sa.sin6_family != AF_INET6)
        rb_raise(rb_eArgError, "addr is not AF_INET6 sockaddr");
    memcpy(&pktinfo.ipi6_addr, &sa.sin6_addr, sizeof(pktinfo.ipi6_addr));

    pktinfo.ipi6_ifindex = ifindex;

    return ancdata_new(AF_INET6, IPPROTO_IPV6, IPV6_PKTINFO, rb_str_new((char *)&pktinfo, sizeof(pktinfo)));
}
Socket::AncillaryData.new(family, cmsg_level, cmsg_type, cmsg_data) → ancillarydata click to toggle source

family should be an integer, a string or a symbol.

  • Socket::AF_INET, “AF_INET”, “INET”, :AF_INET, :INET

  • Socket::AF_UNIX, “AF_UNIX”, “UNIX”, :AF_UNIX, :UNIX

  • etc.

cmsg_level should be an integer, a string or a symbol.

  • Socket::SOL_SOCKET, “SOL_SOCKET”, “SOCKET”, :SOL_SOCKET and :SOCKET

  • Socket::IPPROTO_IP, “IP” and :IP

  • Socket::IPPROTO_IPV6, “IPV6” and :IPV6

  • Socket::IPPROTO_TCP, “TCP” and :TCP

  • etc.

cmsg_type should be an integer, a string or a symbol. If a string/symbol is specified, it is interpreted depend on cmsg_level.

  • Socket::SCM_RIGHTS, “SCM_RIGHTS”, “RIGHTS”, :SCM_RIGHTS, :RIGHTS for SOL_SOCKET

  • Socket::IP_RECVTTL, “RECVTTL” and :RECVTTL for IPPROTO_IP

  • Socket::IPV6_PKTINFO, “PKTINFO” and :PKTINFO for IPPROTO_IPV6

  • etc.

cmsg_data should be a string.

p Socket::AncillaryData.new(:INET, :TCP, :NODELAY, "")
#=> #<Socket::AncillaryData: INET TCP NODELAY "">

p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "")
#=> #<Socket::AncillaryData: INET6 IPV6 PKTINFO "">

static VALUE
ancillary_initialize(VALUE self, VALUE vfamily, VALUE vlevel, VALUE vtype, VALUE data)
{
    int family = rsock_family_arg(vfamily);
    int level = rsock_level_arg(family, vlevel);
    int type = rsock_cmsg_type_arg(family, level, vtype);
    StringValue(data);
    rb_ivar_set(self, rb_intern("family"), INT2NUM(family));
    rb_ivar_set(self, rb_intern("level"), INT2NUM(level));
    rb_ivar_set(self, rb_intern("type"), INT2NUM(type));
    rb_ivar_set(self, rb_intern("data"), data);
    return self;
}
Socket::AncillaryData.unix_rights(io1, io2, ...) → ancillarydata click to toggle source

Creates a new Socket::AncillaryData object which contains file descriptors as data.

p Socket::AncillaryData.unix_rights(STDERR)
#=> #<Socket::AncillaryData: UNIX SOCKET RIGHTS 2>

static VALUE
ancillary_s_unix_rights(int argc, VALUE *argv, VALUE klass)
{
    VALUE result, str, ary;
    int i;

    ary = rb_ary_new();

    for (i = 0 ; i < argc; i++) {
        VALUE obj = argv[i];
        if (!RB_TYPE_P(obj, T_FILE)) {
            rb_raise(rb_eTypeError, "IO expected");
        }
        rb_ary_push(ary, obj);
    }

    str = rb_str_buf_new(sizeof(int) * argc);

    for (i = 0 ; i < argc; i++) {
        VALUE obj = RARRAY_PTR(ary)[i];
        rb_io_t *fptr;
        int fd;
        GetOpenFile(obj, fptr);
        fd = fptr->fd;
        rb_str_buf_cat(str, (char *)&fd, sizeof(int));
    }

    result = ancdata_new(AF_UNIX, SOL_SOCKET, SCM_RIGHTS, str);
    rb_ivar_set(result, rb_intern("unix_rights"), ary);
    return result;
}

Public Instance Methods

cmsg_is?(level, type) → true or false click to toggle source

tests the level and type of ancillarydata.

ancdata = Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "")
ancdata.cmsg_is?(Socket::IPPROTO_IPV6, Socket::IPV6_PKTINFO) #=> true
ancdata.cmsg_is?(:IPV6, :PKTINFO)       #=> true
ancdata.cmsg_is?(:IP, :PKTINFO)         #=> false
ancdata.cmsg_is?(:SOCKET, :RIGHTS)      #=> false

static VALUE
ancillary_cmsg_is_p(VALUE self, VALUE vlevel, VALUE vtype)
{
    int family = ancillary_family(self);
    int level = rsock_level_arg(family, vlevel);
    int type = rsock_cmsg_type_arg(family, level, vtype);

    if (ancillary_level(self) == level &&
        ancillary_type(self) == type)
        return Qtrue;
    else
        return Qfalse;
}
data → string click to toggle source

returns the cmsg data as a string.

p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "").data
#=> ""

static VALUE
ancillary_data(VALUE self)
{
    VALUE v = rb_attr_get(self, rb_intern("data"));
    StringValue(v);
    return v;
}
family → integer click to toggle source

returns the socket family as an integer.

p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "").family
#=> 10

static VALUE
ancillary_family_m(VALUE self)
{
    return INT2NUM(ancillary_family(self));
}
inspect → string click to toggle source

returns a string which shows ancillarydata in human-readable form.

p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "").inspect
#=> "#<Socket::AncillaryData: INET6 IPV6 PKTINFO \"\">"

static VALUE
ancillary_inspect(VALUE self)
{
    VALUE ret;
    int family, level, type;
    VALUE data;
    ID family_id, level_id, type_id;
    VALUE vtype;
    int inspected;

    family = ancillary_family(self);
    level = ancillary_level(self);
    type = ancillary_type(self);
    data = ancillary_data(self);

    ret = rb_sprintf("#<%s:", rb_obj_classname(self));

    family_id = rsock_intern_family_noprefix(family);
    if (family_id)
        rb_str_catf(ret, " %s", rb_id2name(family_id));
    else
        rb_str_catf(ret, " family:%d", family);

    if (level == SOL_SOCKET) {
        rb_str_cat2(ret, " SOCKET");

        type_id = rsock_intern_scm_optname(type);
        if (type_id)
            rb_str_catf(ret, " %s", rb_id2name(type_id));
        else
            rb_str_catf(ret, " cmsg_type:%d", type);
    }
    else if (IS_IP_FAMILY(family)) {
        level_id = rsock_intern_iplevel(level);
        if (level_id)
            rb_str_catf(ret, " %s", rb_id2name(level_id));
        else
            rb_str_catf(ret, " cmsg_level:%d", level);

        vtype = ip_cmsg_type_to_sym(level, type);
        if (SYMBOL_P(vtype))
            rb_str_catf(ret, " %s", rb_id2name(SYM2ID(vtype)));
        else
            rb_str_catf(ret, " cmsg_type:%d", type);
    }
    else {
        rb_str_catf(ret, " cmsg_level:%d", level);
        rb_str_catf(ret, " cmsg_type:%d", type);
    }

    inspected = 0;

    if (level == SOL_SOCKET)
        family = AF_UNSPEC;

    switch (family) {
      case AF_UNSPEC:
        switch (level) {
#        if defined(SOL_SOCKET)
          case SOL_SOCKET:
            switch (type) {
#            if defined(SCM_TIMESTAMP) /* GNU/Linux, FreeBSD, NetBSD, OpenBSD, MacOS X, Solaris */
              case SCM_TIMESTAMP: inspected = inspect_timeval_as_abstime(level, type, data, ret); break;
#            endif
#            if defined(SCM_TIMESTAMPNS) /* GNU/Linux */
              case SCM_TIMESTAMPNS: inspected = inspect_timespec_as_abstime(level, type, data, ret); break;
#            endif
#            if defined(SCM_BINTIME) /* FreeBSD */
              case SCM_BINTIME: inspected = inspect_bintime_as_abstime(level, type, data, ret); break;
#            endif
#            if defined(SCM_RIGHTS) /* 4.4BSD */
              case SCM_RIGHTS: inspected = anc_inspect_socket_rights(level, type, data, ret); break;
#            endif
#            if defined(SCM_CREDENTIALS) /* GNU/Linux */
              case SCM_CREDENTIALS: inspected = anc_inspect_passcred_credentials(level, type, data, ret); break;
#            endif
#            if defined(INSPECT_SCM_CREDS) /* NetBSD */
              case SCM_CREDS: inspected = anc_inspect_socket_creds(level, type, data, ret); break;
#            endif
            }
            break;
#        endif
        }
        break;

      case AF_INET:
#ifdef INET6
      case AF_INET6:
#endif
        switch (level) {
#        if defined(IPPROTO_IP)
          case IPPROTO_IP:
            switch (type) {
#            if defined(IP_RECVDSTADDR) /* 4.4BSD */
              case IP_RECVDSTADDR: inspected = anc_inspect_ip_recvdstaddr(level, type, data, ret); break;
#            endif
#            if defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST) /* GNU/Linux */
              case IP_PKTINFO: inspected = anc_inspect_ip_pktinfo(level, type, data, ret); break;
#            endif
            }
            break;
#        endif

#        if defined(IPPROTO_IPV6)
          case IPPROTO_IPV6:
            switch (type) {
#            if defined(IPV6_PKTINFO) /* RFC 3542 */
              case IPV6_PKTINFO: inspected = anc_inspect_ipv6_pktinfo(level, type, data, ret); break;
#            endif
            }
            break;
#        endif
        }
        break;
    }

    if (!inspected) {
        rb_str_cat2(ret, " ");
        rb_str_append(ret, rb_str_dump(data));
    }

    rb_str_cat2(ret, ">");

    return ret;
}
int → integer click to toggle source

Returns the data in ancillarydata as an int.

The size and endian is dependent on the host.

ancdata = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, STDERR.fileno)
p ancdata.int #=> 2

static VALUE
ancillary_int(VALUE self)
{
    VALUE data;
    int i;
    data = ancillary_data(self);
    if (RSTRING_LEN(data) != sizeof(int))
        rb_raise(rb_eTypeError, "size differ.  expected as sizeof(int)=%d but %ld", (int)sizeof(int), (long)RSTRING_LEN(data));
    memcpy((char*)&i, RSTRING_PTR(data), sizeof(int));
    return INT2NUM(i);
}
ip_pktinfo → [addr, ifindex, spec_dst] click to toggle source

Extracts addr, ifindex and spec_dst from IP_PKTINFO ancillary data.

IP_PKTINFO is not standard.

Supported platform: GNU/Linux

addr = Addrinfo.ip("127.0.0.1")
ifindex = 0
spec_dest = Addrinfo.ip("127.0.0.1")
ancdata = Socket::AncillaryData.ip_pktinfo(addr, ifindex, spec_dest)
p ancdata.ip_pktinfo
#=> [#<Addrinfo: 127.0.0.1>, 0, #<Addrinfo: 127.0.0.1>]

static VALUE
ancillary_ip_pktinfo(VALUE self)
{
    int level, type;
    VALUE data;
    struct in_pktinfo pktinfo;
    struct sockaddr_in sa;
    VALUE v_spec_dst, v_addr;

    level = ancillary_level(self);
    type = ancillary_type(self);
    data = ancillary_data(self);

    if (level != IPPROTO_IP || type != IP_PKTINFO ||
        RSTRING_LEN(data) != sizeof(struct in_pktinfo)) {
        rb_raise(rb_eTypeError, "IP_PKTINFO ancillary data expected");
    }

    memcpy(&pktinfo, RSTRING_PTR(data), sizeof(struct in_pktinfo));
    memset(&sa, 0, sizeof(sa));

    sa.sin_family = AF_INET;
    memcpy(&sa.sin_addr, &pktinfo.ipi_addr, sizeof(sa.sin_addr));
    v_addr = rsock_addrinfo_new((struct sockaddr *)&sa, sizeof(sa), PF_INET, 0, 0, Qnil, Qnil);

    sa.sin_family = AF_INET;
    memcpy(&sa.sin_addr, &pktinfo.ipi_spec_dst, sizeof(sa.sin_addr));
    v_spec_dst = rsock_addrinfo_new((struct sockaddr *)&sa, sizeof(sa), PF_INET, 0, 0, Qnil, Qnil);

    return rb_ary_new3(3, v_addr, UINT2NUM(pktinfo.ipi_ifindex), v_spec_dst);
}
ipv6_pktinfo → [addr, ifindex] click to toggle source

Extracts addr and ifindex from IPV6_PKTINFO ancillary data.

IPV6_PKTINFO is defined by RFC 3542.

addr = Addrinfo.ip("::1")
ifindex = 0
ancdata = Socket::AncillaryData.ipv6_pktinfo(addr, ifindex)
p ancdata.ipv6_pktinfo #=> [#<Addrinfo: ::1>, 0]

static VALUE
ancillary_ipv6_pktinfo(VALUE self)
{
    struct in6_pktinfo pktinfo;
    struct sockaddr_in6 sa;
    VALUE v_addr;

    extract_ipv6_pktinfo(self, &pktinfo, &sa);
    v_addr = rsock_addrinfo_new((struct sockaddr *)&sa, (socklen_t)sizeof(sa), PF_INET6, 0, 0, Qnil, Qnil);
    return rb_ary_new3(2, v_addr, UINT2NUM(pktinfo.ipi6_ifindex));
}
ipv6_pktinfo_addr → addr click to toggle source

Extracts addr from IPV6_PKTINFO ancillary data.

IPV6_PKTINFO is defined by RFC 3542.

addr = Addrinfo.ip("::1")
ifindex = 0
ancdata = Socket::AncillaryData.ipv6_pktinfo(addr, ifindex)
p ancdata.ipv6_pktinfo_addr #=> #<Addrinfo: ::1>

static VALUE
ancillary_ipv6_pktinfo_addr(VALUE self)
{
    struct in6_pktinfo pktinfo;
    struct sockaddr_in6 sa;
    extract_ipv6_pktinfo(self, &pktinfo, &sa);
    return rsock_addrinfo_new((struct sockaddr *)&sa, (socklen_t)sizeof(sa), PF_INET6, 0, 0, Qnil, Qnil);
}
ipv6_pktinfo_ifindex → addr click to toggle source

Extracts ifindex from IPV6_PKTINFO ancillary data.

IPV6_PKTINFO is defined by RFC 3542.

addr = Addrinfo.ip("::1")
ifindex = 0
ancdata = Socket::AncillaryData.ipv6_pktinfo(addr, ifindex)
p ancdata.ipv6_pktinfo_ifindex #=> 0

static VALUE
ancillary_ipv6_pktinfo_ifindex(VALUE self)
{
    struct in6_pktinfo pktinfo;
    struct sockaddr_in6 sa;
    extract_ipv6_pktinfo(self, &pktinfo, &sa);
    return UINT2NUM(pktinfo.ipi6_ifindex);
}
level → integer click to toggle source

returns the cmsg level as an integer.

p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "").level
#=> 41

static VALUE
ancillary_level_m(VALUE self)
{
    return INT2NUM(ancillary_level(self));
}
timestamp → time click to toggle source

returns the timestamp as a time object.

ancillarydata should be one of following type:

  • SOL_SOCKET/SCM_TIMESTAMP (micro second) GNU/Linux, FreeBSD, NetBSD, OpenBSD, Solaris, MacOS X

  • SOL_SOCKET/SCM_TIMESTAMPNS (nano second) GNU/Linux

  • SOL_SOCKET/SCM_BINTIME (2**(-64) second) FreeBSD

    Addrinfo.udp(“127.0.0.1”, 0).bind {|s1|

    Addrinfo.udp("127.0.0.1", 0).bind {|s2|
  s1.setsockopt(:SOCKET, :TIMESTAMP, true)
  s2.send "a", 0, s1.local_address
  ctl = s1.recvmsg.last
  p ctl    #=> #<Socket::AncillaryData: INET SOCKET TIMESTAMP 2009-02-24 17:35:46.775581>
  t = ctl.timestamp
  p t      #=> 2009-02-24 17:35:46 +0900
  p t.usec #=> 775581
  p t.nsec #=> 775581000
}

    }

static VALUE
ancillary_timestamp(VALUE self)
{
    int level, type;
    VALUE data;
    VALUE result = Qnil;

    level = ancillary_level(self);
    type = ancillary_type(self);
    data = ancillary_data(self);

# ifdef SCM_TIMESTAMP
    if (level == SOL_SOCKET && type == SCM_TIMESTAMP &&
        RSTRING_LEN(data) == sizeof(struct timeval)) {
        struct timeval tv;
        memcpy((char*)&tv, RSTRING_PTR(data), sizeof(tv));
        result = rb_time_new(tv.tv_sec, tv.tv_usec);
    }
# endif

# ifdef SCM_TIMESTAMPNS
    if (level == SOL_SOCKET && type == SCM_TIMESTAMPNS &&
        RSTRING_LEN(data) == sizeof(struct timespec)) {
        struct timespec ts;
        memcpy((char*)&ts, RSTRING_PTR(data), sizeof(ts));
        result = rb_time_nano_new(ts.tv_sec, ts.tv_nsec);
    }
# endif

#define add(x,y) (rb_funcall((x), '+', 1, (y)))
#define mul(x,y) (rb_funcall((x), '*', 1, (y)))
#define quo(x,y) (rb_funcall((x), rb_intern("quo"), 1, (y)))

# ifdef SCM_BINTIME
    if (level == SOL_SOCKET && type == SCM_BINTIME &&
        RSTRING_LEN(data) == sizeof(struct bintime)) {
        struct bintime bt;
        VALUE d, timev;
        memcpy((char*)&bt, RSTRING_PTR(data), sizeof(bt));
        d = ULL2NUM(0x100000000ULL);
        d = mul(d,d);
        timev = add(TIMET2NUM(bt.sec), quo(ULL2NUM(bt.frac), d));
        result = rb_time_num_new(timev, Qnil);
    }
# endif

    if (result == Qnil)
        rb_raise(rb_eTypeError, "timestamp ancillary data expected");

    return result;
}
type → integer click to toggle source

returns the cmsg type as an integer.

p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "").type
#=> 2

static VALUE
ancillary_type_m(VALUE self)
{
    return INT2NUM(ancillary_type(self));
}
unix_rights → array-of-IOs or nil click to toggle source

returns the array of IO objects for SCM_RIGHTS control message in UNIX domain socket.

The class of the IO objects in the array is IO or Socket.

The array is attached to ancillarydata when it is instantiated. For example, BasicSocket#recvmsg attach the array when receives a SCM_RIGHTS control message and :scm_rights=>true option is given.

# recvmsg needs :scm_rights=>true for unix_rights
s1, s2 = UNIXSocket.pair
p s1                                         #=> #<UNIXSocket:fd 3>
s1.sendmsg "stdin and a socket", 0, nil, Socket::AncillaryData.unix_rights(STDIN, s1)
_, _, _, ctl = s2.recvmsg(:scm_rights=>true)
p ctl                                        #=> #<Socket::AncillaryData: UNIX SOCKET RIGHTS 6 7>
p ctl.unix_rights                            #=> [#<IO:fd 6>, #<Socket:fd 7>]
p File.identical?(STDIN, ctl.unix_rights[0]) #=> true
p File.identical?(s1, ctl.unix_rights[1])    #=> true

# If :scm_rights=>true is not given, unix_rights returns nil
s1, s2 = UNIXSocket.pair
s1.sendmsg "stdin and a socket", 0, nil, Socket::AncillaryData.unix_rights(STDIN, s1)
_, _, _, ctl = s2.recvmsg
p ctl #=> #<Socket::AncillaryData: UNIX SOCKET RIGHTS 6 7>
p ctl.unix_rights #=> nil

static VALUE
ancillary_unix_rights(VALUE self)
{
    int level, type;

    level = ancillary_level(self);
    type = ancillary_type(self);

    if (level != SOL_SOCKET || type != SCM_RIGHTS)
        rb_raise(rb_eTypeError, "SCM_RIGHTS ancillary data expected");

    return rb_attr_get(self, rb_intern("unix_rights"));
}


class Socket::Option - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Socket::Option

Socket::Option represents a socket option used by BasicSocket#getsockopt and BasicSocket#setsockopt. A socket option contains the socket family, protocol level, option name optname and option value data.

In Files

  • lib/ipaddr.rb

Parent

Object

Public Class Methods

Socket::Option.bool(family, level, optname, bool) → sockopt click to toggle source

Creates a new Socket::Option object which contains boolean as data. Actually 0 or 1 as int is used.

p Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, true)
#=> #<Socket::Option: INET SOCKET KEEPALIVE 1>

p Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, false)
#=> #<Socket::Option: AF_INET SOCKET KEEPALIVE 0>

static VALUE
sockopt_s_bool(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vbool)
{
    int family = rsock_family_arg(vfamily);
    int level = rsock_level_arg(family, vlevel);
    int optname = rsock_optname_arg(family, level, voptname);
    int i = RTEST(vbool) ? 1 : 0;
    return rsock_sockopt_new(family, level, optname, rb_str_new((char*)&i, sizeof(i)));
}
Socket::Option.int(family, level, optname, integer) → sockopt click to toggle source

Creates a new Socket::Option object which contains an int as data.

The size and endian is dependent on the platform.

p Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 1)
#=> #<Socket::Option: INET SOCKET KEEPALIVE 1>

static VALUE
sockopt_s_int(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vint)
{
    int family = rsock_family_arg(vfamily);
    int level = rsock_level_arg(family, vlevel);
    int optname = rsock_optname_arg(family, level, voptname);
    int i = NUM2INT(vint);
    return rsock_sockopt_new(family, level, optname, rb_str_new((char*)&i, sizeof(i)));
}
Socket::Option.linger(onoff, secs) → sockopt click to toggle source

Creates a new Socket::Option object for SOL_SOCKET/SO_LINGER.

onoff should be an integer or a boolean.

secs should be the number of seconds.

p Socket::Option.linger(true, 10)
#=> #<Socket::Option: UNSPEC SOCKET LINGER on 10sec>

static VALUE
sockopt_s_linger(VALUE klass, VALUE vonoff, VALUE vsecs)
{
    VALUE tmp;
    struct linger l;
    memset(&l, 0, sizeof(l));
    if (!NIL_P(tmp = rb_check_to_integer(vonoff, "to_int")))
        l.l_onoff = NUM2INT(tmp);
    else
        l.l_onoff = RTEST(vonoff) ? 1 : 0;
    l.l_linger = NUM2INT(vsecs);
    return rsock_sockopt_new(AF_UNSPEC, SOL_SOCKET, SO_LINGER, rb_str_new((char*)&l, sizeof(l)));
}
Socket::Option.new(family, level, optname, data) → sockopt click to toggle source

Returns a new Socket::Option object.

sockopt = Socket::Option.new(:INET, :SOCKET, :KEEPALIVE, [1].pack("i"))
p sockopt #=> #<Socket::Option: INET SOCKET KEEPALIVE 1>

static VALUE
sockopt_initialize(VALUE self, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE data)
{
    int family = rsock_family_arg(vfamily);
    int level = rsock_level_arg(family, vlevel);
    int optname = rsock_optname_arg(family, level, voptname);
    StringValue(data);
    rb_ivar_set(self, rb_intern("family"), INT2NUM(family));
    rb_ivar_set(self, rb_intern("level"), INT2NUM(level));
    rb_ivar_set(self, rb_intern("optname"), INT2NUM(optname));
    rb_ivar_set(self, rb_intern("data"), data);
    return self;
}

Public Instance Methods

bool → true or false click to toggle source

Returns the data in sockopt as an boolean value.

sockopt = Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 1)
p sockopt.bool => true

static VALUE
sockopt_bool(VALUE self)
{
    int i;
    VALUE data = sockopt_data(self);
    StringValue(data);
    if (RSTRING_LEN(data) != sizeof(int))
        rb_raise(rb_eTypeError, "size differ.  expected as sizeof(int)=%d but %ld",
                 (int)sizeof(int), (long)RSTRING_LEN(data));
    memcpy((char*)&i, RSTRING_PTR(data), sizeof(int));
    return i == 0 ? Qfalse : Qtrue;
}
data → string click to toggle source

returns the socket option data as a string.

p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).data
#=> "\x01\x00\x00\x00"

static VALUE
sockopt_data(VALUE self)
{
    VALUE v = rb_attr_get(self, rb_intern("data"));
    StringValue(v);
    return v;
}
family → integer click to toggle source

returns the socket family as an integer.

p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).family
#=> 10

static VALUE
sockopt_family_m(VALUE self)
{
    return rb_attr_get(self, rb_intern("family"));
}
inspect → string click to toggle source

Returns a string which shows sockopt in human-readable form.

p Socket::Option.new(:INET, :SOCKET, :KEEPALIVE, [1].pack("i")).inspect
#=> "#<Socket::Option: INET SOCKET KEEPALIVE 1>"

static VALUE
sockopt_inspect(VALUE self)
{
    int family = NUM2INT(sockopt_family_m(self));
    int level = NUM2INT(sockopt_level_m(self));
    int optname = NUM2INT(sockopt_optname_m(self));
    VALUE data = sockopt_data(self);
    VALUE v, ret;
    ID family_id, level_id, optname_id;
    int inspected;

    StringValue(data);

    ret = rb_sprintf("#<%s:", rb_obj_classname(self));

    family_id = rsock_intern_family_noprefix(family);
    if (family_id)
        rb_str_catf(ret, " %s", rb_id2name(family_id));
    else
        rb_str_catf(ret, " family:%d", family);

    if (level == SOL_SOCKET) {
        rb_str_cat2(ret, " SOCKET");

        optname_id = rsock_intern_so_optname(optname);
        if (optname_id)
            rb_str_catf(ret, " %s", rb_id2name(optname_id));
        else
            rb_str_catf(ret, " optname:%d", optname);
    }
#ifdef HAVE_SYS_UN_H
    else if (family == AF_UNIX) {
        rb_str_catf(ret, " level:%d", level);

        optname_id = rsock_intern_local_optname(optname);
        if (optname_id)
            rb_str_catf(ret, " %s", rb_id2name(optname_id));
        else
            rb_str_catf(ret, " optname:%d", optname);
    }
#endif
    else if (IS_IP_FAMILY(family)) {
        level_id = rsock_intern_iplevel(level);
        if (level_id)
            rb_str_catf(ret, " %s", rb_id2name(level_id));
        else
            rb_str_catf(ret, " level:%d", level);

        v = optname_to_sym(level, optname);
        if (SYMBOL_P(v))
            rb_str_catf(ret, " %s", rb_id2name(SYM2ID(v)));
        else
            rb_str_catf(ret, " optname:%d", optname);
    }
    else {
        rb_str_catf(ret, " level:%d", level);
        rb_str_catf(ret, " optname:%d", optname);
    }

    inspected = 0;

    if (level == SOL_SOCKET)
        family = AF_UNSPEC;
    switch (family) {
      case AF_UNSPEC:
        switch (level) {
          case SOL_SOCKET:
            switch (optname) {
#            if defined(SO_DEBUG) /* POSIX */
              case SO_DEBUG: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(SO_ERROR) /* POSIX */
              case SO_ERROR: inspected = inspect_errno(level, optname, data, ret); break;
#            endif
#            if defined(SO_TYPE) /* POSIX */
              case SO_TYPE: inspected = inspect_socktype(level, optname, data, ret); break;
#            endif
#            if defined(SO_ACCEPTCONN) /* POSIX */
              case SO_ACCEPTCONN: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(SO_BROADCAST) /* POSIX */
              case SO_BROADCAST: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(SO_REUSEADDR) /* POSIX */
              case SO_REUSEADDR: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(SO_KEEPALIVE) /* POSIX */
              case SO_KEEPALIVE: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(SO_OOBINLINE) /* POSIX */
              case SO_OOBINLINE: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(SO_SNDBUF) /* POSIX */
              case SO_SNDBUF: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(SO_RCVBUF) /* POSIX */
              case SO_RCVBUF: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(SO_DONTROUTE) /* POSIX */
              case SO_DONTROUTE: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(SO_RCVLOWAT) /* POSIX */
              case SO_RCVLOWAT: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(SO_SNDLOWAT) /* POSIX */
              case SO_SNDLOWAT: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(SO_LINGER) /* POSIX */
              case SO_LINGER: inspected = inspect_linger(level, optname, data, ret); break;
#            endif
#            if defined(SO_RCVTIMEO) /* POSIX */
              case SO_RCVTIMEO: inspected = inspect_timeval_as_interval(level, optname, data, ret); break;
#            endif
#            if defined(SO_SNDTIMEO) /* POSIX */
              case SO_SNDTIMEO: inspected = inspect_timeval_as_interval(level, optname, data, ret); break;
#            endif
#            if defined(SO_PEERCRED) /* GNU/Linux, OpenBSD */
              case SO_PEERCRED: inspected = inspect_peercred(level, optname, data, ret); break;
#            endif
            }
            break;
        }
        break;

      case AF_INET:
#ifdef INET6
      case AF_INET6:
#endif
        switch (level) {
#        if defined(IPPROTO_IP)
          case IPPROTO_IP:
            switch (optname) {
#            if defined(IP_MULTICAST_IF) && defined(HAVE_TYPE_STRUCT_IP_MREQN) /* 4.4BSD, GNU/Linux */
              case IP_MULTICAST_IF: inspected = inspect_ipv4_multicast_if(level, optname, data, ret); break;
#            endif
#            if defined(IP_ADD_MEMBERSHIP) /* 4.4BSD, GNU/Linux */
              case IP_ADD_MEMBERSHIP: inspected = inspect_ipv4_add_drop_membership(level, optname, data, ret); break;
#            endif
#            if defined(IP_DROP_MEMBERSHIP) /* 4.4BSD, GNU/Linux */
              case IP_DROP_MEMBERSHIP: inspected = inspect_ipv4_add_drop_membership(level, optname, data, ret); break;
#            endif
            }
            break;
#        endif

#        if defined(IPPROTO_IPV6)
          case IPPROTO_IPV6:
            switch (optname) {
#            if defined(IPV6_MULTICAST_HOPS) /* POSIX */
              case IPV6_MULTICAST_HOPS: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(IPV6_MULTICAST_IF) /* POSIX */
              case IPV6_MULTICAST_IF: inspected = inspect_ipv6_multicast_if(level, optname, data, ret); break;
#            endif
#            if defined(IPV6_MULTICAST_LOOP) /* POSIX */
              case IPV6_MULTICAST_LOOP: inspected = inspect_uint(level, optname, data, ret); break;
#            endif
#            if defined(IPV6_JOIN_GROUP) /* POSIX */
              case IPV6_JOIN_GROUP: inspected = inspect_ipv6_mreq(level, optname, data, ret); break;
#            endif
#            if defined(IPV6_LEAVE_GROUP) /* POSIX */
              case IPV6_LEAVE_GROUP: inspected = inspect_ipv6_mreq(level, optname, data, ret); break;
#            endif
#            if defined(IPV6_UNICAST_HOPS) /* POSIX */
              case IPV6_UNICAST_HOPS: inspected = inspect_int(level, optname, data, ret); break;
#            endif
#            if defined(IPV6_V6ONLY) /* POSIX */
              case IPV6_V6ONLY: inspected = inspect_int(level, optname, data, ret); break;
#            endif
            }
            break;
#        endif

#        if defined(IPPROTO_TCP)
          case IPPROTO_TCP:
            switch (optname) {
#            if defined(TCP_NODELAY) /* POSIX */
              case TCP_NODELAY: inspected = inspect_int(level, optname, data, ret); break;
#            endif
            }
            break;
#        endif
        }
        break;

#ifdef HAVE_SYS_UN_H
      case AF_UNIX:
        switch (level) {
          case 0:
            switch (optname) {
#            if defined(LOCAL_PEERCRED)
              case LOCAL_PEERCRED: inspected = inspect_local_peercred(level, optname, data, ret); break;
#            endif
            }
            break;
        }
        break;
#endif
    }

    if (!inspected) {
        rb_str_cat2(ret, " ");
        rb_str_append(ret, rb_str_dump(data));
    }

    rb_str_cat2(ret, ">");

    return ret;
}
int → integer click to toggle source

Returns the data in sockopt as an int.

The size and endian is dependent on the platform.

sockopt = Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 1)
p sockopt.int => 1

static VALUE
sockopt_int(VALUE self)
{
    int i;
    VALUE data = sockopt_data(self);
    StringValue(data);
    if (RSTRING_LEN(data) != sizeof(int))
        rb_raise(rb_eTypeError, "size differ.  expected as sizeof(int)=%d but %ld",
                 (int)sizeof(int), (long)RSTRING_LEN(data));
    memcpy((char*)&i, RSTRING_PTR(data), sizeof(int));
    return INT2NUM(i);
}
level → integer click to toggle source

returns the socket level as an integer.

p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).level
#=> 41

static VALUE
sockopt_level_m(VALUE self)
{
    return INT2NUM(sockopt_level(self));
}
linger → [bool, seconds] click to toggle source

Returns the linger data in sockopt as a pair of boolean and integer.

sockopt = Socket::Option.linger(true, 10)
p sockopt.linger => [true, 10]

static VALUE
sockopt_linger(VALUE self)
{
    int level = sockopt_level(self);
    int optname = sockopt_optname(self);
    VALUE data = sockopt_data(self);
    struct linger l;
    VALUE vonoff, vsecs;

    if (level != SOL_SOCKET || optname != SO_LINGER)
        rb_raise(rb_eTypeError, "linger socket option expected");
    if (RSTRING_LEN(data) != sizeof(l))
        rb_raise(rb_eTypeError, "size differ.  expected as sizeof(struct linger)=%d but %ld",
                 (int)sizeof(struct linger), (long)RSTRING_LEN(data));
    memcpy((char*)&l, RSTRING_PTR(data), sizeof(struct linger));
    switch (l.l_onoff) {
      case 0: vonoff = Qfalse; break;
      case 1: vonoff = Qtrue; break;
      default: vonoff = INT2NUM(l.l_onoff); break;
    }
    vsecs = INT2NUM(l.l_linger);
    return rb_assoc_new(vonoff, vsecs);
}
optname → integer click to toggle source

returns the socket option name as an integer.

p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).optname
#=> 2

static VALUE
sockopt_optname_m(VALUE self)
{
    return INT2NUM(sockopt_optname(self));
}
data → string click to toggle source

returns the socket option data as a string.

p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).data
#=> "\x01\x00\x00\x00"

static VALUE
sockopt_data(VALUE self)
{
    VALUE v = rb_attr_get(self, rb_intern("data"));
    StringValue(v);
    return v;
}
unpack(template) → array click to toggle source

Calls String#unpack on sockopt.data.

sockopt = Socket::Option.new(:INET, :SOCKET, :KEEPALIVE, [1].pack("i"))
p sockopt.unpack("i")      #=> [1]
p sockopt.data.unpack("i") #=> [1]

static VALUE
sockopt_unpack(VALUE self, VALUE template)
{
    return rb_funcall(sockopt_data(self), rb_intern("unpack"), 1, template);
}


class Socket::UDPSource - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Socket::UDPSource

UDP/IP address information used by Socket.udp_server_loop.

In Files

  • ext/socket/lib/socket.rb

Parent

Object

Attributes

local_address[R]

Local address

remote_address[R]

Address of the source

Public Class Methods

new(remote_address, local_address, &reply_proc) click to toggle source

remote_address is an Addrinfo object.

local_address is an Addrinfo object.

reply_proc is a Proc used to send reply back to the source.

# File ext/socket/lib/socket.rb, line 745
def initialize(remote_address, local_address, &reply_proc)
  @remote_address = remote_address
  @local_address = local_address
  @reply_proc = reply_proc
end

Public Instance Methods

reply(msg) click to toggle source

Sends the String msg to the source

# File ext/socket/lib/socket.rb, line 762
def reply(msg)
  @reply_proc.call msg
end


class SocketError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class SocketError

SocketError is the error class for socket.

In Files

  • ext/socket/init.c

Parent

StandardError


class SortedSet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class SortedSet

SortedSet implements a Set that guarantees that it's element are yielded in sorted order (according to the return values of their #<=> methods) when iterating over them.

All elements that are added to a SortedSet must respond to the <=> method for comparison.

Also, all elements must be mutually comparable: el1 <=> el2 must not return nil for any elements el1 and el2, else an ArgumentError will be raised when iterating over the SortedSet.

Example

require "set"

set = SortedSet.new([2, 1, 5, 6, 4, 5, 3, 3, 3])
ary = []

set.each do |obj|
  ary << obj
end

p ary # => [1, 2, 3, 4, 5, 6]

set2 = SortedSet.new([1, 2, "3"])
set2.each { |obj| } # => raises ArgumentError: comparison of Fixnum with String failed

In Files

  • lib/set.rb

Parent

Set


class SshDirPublisher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class SshDirPublisher

Publish an entire directory to an existing remote directory using SSH.

In Files

  • lib/rake/contrib/publisher.rb

Parent

Object

Public Class Methods

new(host, remote_dir, local_dir) click to toggle source
# File lib/rake/contrib/publisher.rb, line 37
def initialize(host, remote_dir, local_dir)
  @host = host
  @remote_dir = remote_dir
  @local_dir = local_dir
end

Public Instance Methods

upload() click to toggle source
# File lib/rake/contrib/publisher.rb, line 43
def upload
  run %Q{scp -rq #{@local_dir}/* #{@host}:#{@remote_dir}}
end


class SshFilePublisher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class SshFilePublisher

Publish a list of files to an existing remote directory.

In Files

  • lib/rake/contrib/publisher.rb

Parent

Object

Public Class Methods

new(host, remote_dir, local_dir, *files) click to toggle source

Create a publisher using the give host information.

# File lib/rake/contrib/publisher.rb, line 60
def initialize(host, remote_dir, local_dir, *files)
  @host = host
  @remote_dir = remote_dir
  @local_dir = local_dir
  @files = files
end

Public Instance Methods

upload() click to toggle source

Upload the local directory to the remote directory.

# File lib/rake/contrib/publisher.rb, line 68
def upload
  @files.each do |fn|
    run %Q{scp -q #{@local_dir}/#{fn} #{@host}:#{@remote_dir}}
  end
end


class SshFreshDirPublisher - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class SshFreshDirPublisher

Publish an entire directory to a fresh remote directory using SSH.

In Files

  • lib/rake/contrib/publisher.rb

Parent

SshDirPublisher

Public Instance Methods

upload() click to toggle source
# File lib/rake/contrib/publisher.rb, line 50
def upload
  run %Q{ssh #{@host} rm -rf #{@remote_dir}} rescue nil
  run %Q{ssh #{@host} mkdir #{@remote_dir}}
  super
end


class String - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class String

Rake extension methods for String.

In Files

  • lib/csv.rb
  • lib/mkmf.rb
  • lib/rake/ext/string.rb
  • lib/scanf.rb
  • lib/shellwords.rb
  • ext/bigdecimal/lib/bigdecimal/util.rb
  • ext/nkf/lib/kconv.rb

Parent

Object

Public Instance Methods

ext(newext='') click to toggle source

Replace the file extension with newext. If there is no extension on the string, append the new extension to the end. If the new extension is not given, or is the empty string, remove any existing extension.

ext is a user added method for the String class.

# File lib/rake/ext/string.rb, line 14
def ext(newext='')
  return self.dup if ['.', '..'].include? self
  if newext != ''
    newext = (newext =~ /^\./) ? newext : ("." + newext)
  end
  self.chomp(File.extname(self)) << newext
end
pathmap(spec=nil, &block) click to toggle source

Map the path according to the given specification. The specification controls the details of the mapping. The following special patterns are recognized:

  • %p – The complete path.

  • %f – The base file name of the path, with its file extension, but without any directories.

  • %n – The file name of the path without its file extension.

  • %d – The directory list of the path.

  • %x – The file extension of the path. An empty string if there is no extension.

  • %X – Everything but the file extension.

  • %s – The alternate file separator if defined, otherwise use the standard file separator.

  • %% – A percent sign.

The %d specifier can also have a numeric prefix (e.g. '%2d'). If the number is positive, only return (up to) n directories in the path, starting from the left hand side. If n is negative, return (up to) |n| directories from the right hand side of the path.

Examples:

'a/b/c/d/file.txt'.pathmap("%2d")   => 'a/b'
'a/b/c/d/file.txt'.pathmap("%-2d")  => 'c/d'

Also the %d, %p, %f, %n, %x, and %X operators can take a pattern/replacement argument to perform simple string substitutions on a particular part of the path. The pattern and replacement are separated by a comma and are enclosed by curly braces. The replacement spec comes after the % character but before the operator letter. (e.g. “%{old,new}d”). Multiple replacement specs should be separated by semi-colons (e.g. “%{old,new;src,bin}d”).

Regular expressions may be used for the pattern, and back refs may be used in the replacement text. Curly braces, commas and semi-colons are excluded from both the pattern and replacement text (let's keep parsing reasonable).

For example:

"src/org/onestepback/proj/A.java".pathmap("%{^src,bin}X.class")

returns:

"bin/org/onestepback/proj/A.class"

If the replacement text is '*', then a block may be provided to perform some arbitrary calculation for the replacement.

For example:

"/path/to/file.TXT".pathmap("%X%{.*,*}x") { |ext|
   ext.downcase
}

Returns:

"/path/to/file.txt"
# File lib/rake/ext/string.rb, line 130
def pathmap(spec=nil, &block)
  return self if spec.nil?
  result = ''
  spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag|
    case frag
    when '%f'
      result << File.basename(self)
    when '%n'
      result << File.basename(self).ext
    when '%d'
      result << File.dirname(self)
    when '%x'
      result << File.extname(self)
    when '%X'
      result << self.ext
    when '%p'
      result << self
    when '%s'
      result << (File::ALT_SEPARATOR || File::SEPARATOR)
    when '%-'
      # do nothing
    when '%%'
      result << "%"
    when /%(-?\d+)d/
      result << pathmap_partial($1.to_i)
    when /^%\{([^}]*)\}(\d*[dpfnxX])/
      patterns, operator = $1, $2
      result << pathmap('%' + operator).pathmap_replace(patterns, &block)
    when /^%/
      fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'"
    else
      result << frag
    end
  end
  result
end
pathmap_explode() click to toggle source

Explode a path into individual components. Used by pathmap.

# File lib/rake/ext/string.rb, line 25
def pathmap_explode
  head, tail = File.split(self)
  return [self] if head == self
  return [tail] if head == '.' || tail == '/'
  return [head, tail] if head == '/'
  return head.pathmap_explode + [tail]
end
pathmap_partial(n) click to toggle source

Extract a partial path from the path. Include n directories from the front end (left hand side) if n is positive. Include |n| directories from the back end (right hand side) if n is negative.

# File lib/rake/ext/string.rb, line 37
def pathmap_partial(n)
  dirs = File.dirname(self).pathmap_explode
  partial_dirs =
    if n > 0
      dirs[0...n]
    elsif n < 0
      dirs.reverse[0...-n].reverse
    else
      "."
    end
  File.join(partial_dirs)
end
pathmap_replace(patterns, &block) click to toggle source

Preform the pathmap replacement operations on the given path. The patterns take the form 'pat1,rep1;pat2,rep2…'.

# File lib/rake/ext/string.rb, line 53
def pathmap_replace(patterns, &block)
  result = self
  patterns.split(';').each do |pair|
    pattern, replacement = pair.split(',')
    pattern = Regexp.new(pattern)
    if replacement == '*' && block_given?
      result = result.sub(pattern, &block)
    elsif replacement
      result = result.sub(pattern, replacement)
    else
      result = result.sub(pattern, '')
    end
  end
  result
end

scanf

↑ top

You will need to require 'scanf' to use these methods

Public Instance Methods

block_scanf(fstr) { |current_match| ... } click to toggle source

Scans the current string until the match is exhausted yielding each match as it is encountered in the string. A block is not necessary as the results will simply be aggregated into the final array.

"123 456".block_scanf("%d")
# => [123, 456]

If a block is given, the value from that is returned from the yield is added to an output array.

"123 456".block_scanf("%d) do |digit,| # the ',' unpacks the Array
  digit + 100
end
# => [223, 556]

See Scanf for details on creating a format string.

You will need to require 'scanf' to use #block_scanf

# File lib/scanf.rb, line 748
def block_scanf(fstr) #:yield: current_match
  fs = Scanf::FormatString.new(fstr)
  str = self.dup
  final = []
  begin
    current = str.scanf(fs)
    final.push(yield(current)) unless current.empty?
    str = fs.string_left
  end until current.empty? || str.empty?
  return final
end
String#iseuc → true or false click to toggle source

Returns whether self's encoding is EUC-JP or not.

# File ext/nkf/lib/kconv.rb, line 263
def iseuc;    Kconv.iseuc(self) end
String#isjis → true or false click to toggle source

Returns whether self's encoding is ISO-2022-JP or not.

# File ext/nkf/lib/kconv.rb, line 275
def isjis;    Kconv.isjis(self) end
String#issjis → true or false click to toggle source

Returns whether self's encoding is Shift_JIS or not.

# File ext/nkf/lib/kconv.rb, line 269
def issjis;   Kconv.issjis(self) end
String#isutf8 → true or false click to toggle source

Returns whether self's encoding is UTF-8 or not.

# File ext/nkf/lib/kconv.rb, line 281
def isutf8;   Kconv.isutf8(self) end
String#kconv(to_enc, from_enc) click to toggle source

Convert self to to_enc. to_enc and from_enc are given as constants of Kconv or Encoding objects.

# File ext/nkf/lib/kconv.rb, line 204
def kconv(to_enc, from_enc=nil)
  from_enc = self.encoding if !from_enc && self.encoding != Encoding.list[0]
  Kconv::kconv(self, to_enc, from_enc)
end
scanf(fstr) { |current_match| ... } click to toggle source

Scans the current string. If a block is given, it functions exactly like block_scanf.

arr = "123 456".scanf("%d%d")
# => [123, 456]

require 'pp'

"this 123 read that 456 other".scanf("%s%d%s") {|m| pp m}

# ["this", 123, "read"]
# ["that", 456, "other"]
# => [["this", 123, "read"], ["that", 456, "other"]]

See Scanf for details on creating a format string.

You will need to require 'scanf' to use #scanf

# File lib/scanf.rb, line 715
def scanf(fstr,&b) #:yield: current_match
  if b
    block_scanf(fstr,&b)
  else
    fs =
      if fstr.is_a? Scanf::FormatString
        fstr
      else
        Scanf::FormatString.new(fstr)
      end
    fs.match(self)
  end
end
shellescape → string click to toggle source

Escapes str so that it can be safely used in a Bourne shell command line.

See Shellwords.shellescape for details.

# File lib/shellwords.rb, line 199
def shellescape
  Shellwords.escape(self)
end
shellsplit → array click to toggle source

Splits str into an array of tokens in the same way the UNIX Bourne shell does.

See Shellwords.shellsplit for details.

# File lib/shellwords.rb, line 188
def shellsplit
  Shellwords.split(self)
end
to_d → bigdecimal click to toggle source

Convert string to a BigDecimal and return it.

require 'bigdecimal'
require 'bigdecimal/util'

"0.5".to_d
# => #<BigDecimal:1dc69e0,'0.5E0',9(18)>

# File ext/bigdecimal/lib/bigdecimal/util.rb, line 47
def to_d
  BigDecimal(self)
end
String#toeuc → string click to toggle source

Convert self to EUC-JP

# File ext/nkf/lib/kconv.rb, line 223
def toeuc; Kconv.toeuc(self) end
String#tojis → string click to toggle source

Convert self to ISO-2022-JP

# File ext/nkf/lib/kconv.rb, line 217
def tojis; Kconv.tojis(self) end
String#tolocale → string click to toggle source

Convert self to locale encoding

# File ext/nkf/lib/kconv.rb, line 253
def tolocale; Kconv.tolocale(self) end
String#tosjis → string click to toggle source

Convert self to Shift_JIS

# File ext/nkf/lib/kconv.rb, line 229
def tosjis; Kconv.tosjis(self) end
String#toutf16 → string click to toggle source

Convert self to UTF-16

# File ext/nkf/lib/kconv.rb, line 241
def toutf16; Kconv.toutf16(self) end
String#toutf32 → string click to toggle source

Convert self to UTF-32

# File ext/nkf/lib/kconv.rb, line 247
def toutf32; Kconv.toutf32(self) end
String#toutf8 → string click to toggle source

Convert self to UTF-8

# File ext/nkf/lib/kconv.rb, line 235
def toutf8; Kconv.toutf8(self) end


class StringIO - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class StringIO

Pseudo I/O on String object.

In Files

  • ext/stringio/stringio.c

Parent

Data

Included Modules

  • Enumerable
  • IO::readable
  • IO::writable

Public Class Methods

new(string=""[, mode]) click to toggle source

Creates new StringIO instance from with string and mode.

static VALUE
strio_initialize(int argc, VALUE *argv, VALUE self)
{
    struct StringIO *ptr = check_strio(self);

    if (!ptr) {
        DATA_PTR(self) = ptr = strio_alloc();
    }
    rb_call_super(0, 0);
    strio_init(argc, argv, ptr, self);
    return self;
}
open(string=""[, mode]) {|strio| ...} click to toggle source

Equivalent to ::new except that when it is called with a block, it yields with the new instance and closes it, and returns the result which returned from the block.

static VALUE
strio_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE obj = rb_class_new_instance(argc, argv, klass);
    if (!rb_block_given_p()) return obj;
    return rb_ensure(rb_yield, obj, strio_finalize, obj);
}

Public Instance Methods

binmode → true click to toggle source
#define strio_binmode strio_self
bytes() click to toggle source

This is a deprecated alias for each_byte.

static VALUE
strio_bytes(VALUE self)
{
    rb_warn("StringIO#bytes is deprecated; use #each_byte instead");
    if (!rb_block_given_p())
        return rb_enumeratorize(self, ID2SYM(rb_intern("each_byte")), 0, 0);
    return strio_each_byte(self);
}
chars() click to toggle source

This is a deprecated alias for each_char.

static VALUE
strio_chars(VALUE self)
{
    rb_warn("StringIO#chars is deprecated; use #each_char instead");
    if (!rb_block_given_p())
        return rb_enumeratorize(self, ID2SYM(rb_intern("each_char")), 0, 0);
    return strio_each_char(self);
}
close → nil click to toggle source

Closes strio. The strio is unavailable for any further data operations; an IOError is raised if such an attempt is made.

static VALUE
strio_close(VALUE self)
{
    StringIO(self);
    if (CLOSED(self)) {
        rb_raise(rb_eIOError, "closed stream");
    }
    RBASIC(self)->flags &= ~STRIO_READWRITE;
    return Qnil;
}
close_read → nil click to toggle source

Closes the read end of a StringIO. Will raise an IOError if the strio is not readable.

static VALUE
strio_close_read(VALUE self)
{
    StringIO(self);
    if (!READABLE(self)) {
        rb_raise(rb_eIOError, "closing non-duplex IO for reading");
    }
    RBASIC(self)->flags &= ~STRIO_READABLE;
    return Qnil;
}
close_write → nil click to toggle source

Closes the write end of a StringIO. Will raise an IOError if the strio is not writeable.

static VALUE
strio_close_write(VALUE self)
{
    StringIO(self);
    if (!WRITABLE(self)) {
        rb_raise(rb_eIOError, "closing non-duplex IO for writing");
    }
    RBASIC(self)->flags &= ~STRIO_WRITABLE;
    return Qnil;
}
closed? → true or false click to toggle source

Returns true if strio is completely closed, false otherwise.

static VALUE
strio_closed(VALUE self)
{
    StringIO(self);
    if (!CLOSED(self)) return Qfalse;
    return Qtrue;
}
closed_read? → true or false click to toggle source

Returns true if strio is not readable, false otherwise.

static VALUE
strio_closed_read(VALUE self)
{
    StringIO(self);
    if (READABLE(self)) return Qfalse;
    return Qtrue;
}
closed_write? → true or false click to toggle source

Returns true if strio is not writable, false otherwise.

static VALUE
strio_closed_write(VALUE self)
{
    StringIO(self);
    if (WRITABLE(self)) return Qfalse;
    return Qtrue;
}
codepoints() click to toggle source

This is a deprecated alias for each_codepoint.

static VALUE
strio_codepoints(VALUE self)
{
    rb_warn("StringIO#codepoints is deprecated; use #each_codepoint instead");
    if (!rb_block_given_p())
        return rb_enumeratorize(self, ID2SYM(rb_intern("each_codepoint")), 0, 0);
    return strio_each_codepoint(self);
}
each(sep=$/) {|line| block } → strio click to toggle source
each(limit) {|line| block } → strio
each(sep, limit) {|line| block } → strio
each(...) → anEnumerator
each_line(sep=$/) {|line| block } → strio
each_line(limit) {|line| block } → strio
each_line(sep,limit) {|line| block } → strio
each_line(...) → anEnumerator

See IO#each.

static VALUE
strio_each(int argc, VALUE *argv, VALUE self)
{
    VALUE line;

    StringIO(self);
    RETURN_ENUMERATOR(self, argc, argv);

    if (argc > 0 && !NIL_P(argv[argc-1]) && NIL_P(rb_check_string_type(argv[argc-1])) &&
        NUM2LONG(argv[argc-1]) == 0) {
        rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
    }

    while (!NIL_P(line = strio_getline(argc, argv, readable(self)))) {
        rb_yield(line);
    }
    return self;
}
each_byte {|byte| block } → strio click to toggle source
each_byte → anEnumerator

See IO#each_byte.

static VALUE
strio_each_byte(VALUE self)
{
    struct StringIO *ptr = readable(self);

    RETURN_ENUMERATOR(self, 0, 0);

    while (ptr->pos < RSTRING_LEN(ptr->string)) {
        char c = RSTRING_PTR(ptr->string)[ptr->pos++];
        rb_yield(CHR2FIX(c));
    }
    return self;
}
each_char {|char| block } → strio click to toggle source
each_char → anEnumerator

See IO#each_char.

static VALUE
strio_each_char(VALUE self)
{
    VALUE c;

    RETURN_ENUMERATOR(self, 0, 0);

    while (!NIL_P(c = strio_getc(self))) {
        rb_yield(c);
    }
    return self;
}
each_codepoint {|c| block } → strio click to toggle source
each_codepoint → anEnumerator

See IO#each_codepoint.

static VALUE
strio_each_codepoint(VALUE self)
{
    struct StringIO *ptr;
    rb_encoding *enc;
    unsigned int c;
    int n;

    RETURN_ENUMERATOR(self, 0, 0);

    ptr = readable(self);
    enc = rb_enc_get(ptr->string);
    for (;;) {
        if (ptr->pos >= RSTRING_LEN(ptr->string)) {
            return self;
        }

        c = rb_enc_codepoint_len(RSTRING_PTR(ptr->string)+ptr->pos,
                                 RSTRING_END(ptr->string), &n, enc);
        rb_yield(UINT2NUM(c));
        ptr->pos += n;
    }
    return self;
}
each(sep=$/) {|line| block } → strio click to toggle source
each(limit) {|line| block } → strio
each(sep, limit) {|line| block } → strio
each(...) → anEnumerator
each_line(sep=$/) {|line| block } → strio
each_line(limit) {|line| block } → strio
each_line(sep,limit) {|line| block } → strio
each_line(...) → anEnumerator

See IO#each.

static VALUE
strio_each(int argc, VALUE *argv, VALUE self)
{
    VALUE line;

    StringIO(self);
    RETURN_ENUMERATOR(self, argc, argv);

    if (argc > 0 && !NIL_P(argv[argc-1]) && NIL_P(rb_check_string_type(argv[argc-1])) &&
        NUM2LONG(argv[argc-1]) == 0) {
        rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
    }

    while (!NIL_P(line = strio_getline(argc, argv, readable(self)))) {
        rb_yield(line);
    }
    return self;
}
eof → true or false click to toggle source
eof? → true or false

Returns true if strio is at end of file. The stringio must be opened for reading or an IOError will be raised.

static VALUE
strio_eof(VALUE self)
{
    struct StringIO *ptr = readable(self);
    if (ptr->pos < RSTRING_LEN(ptr->string)) return Qfalse;
    return Qtrue;
}
eof → true or false click to toggle source
eof? → true or false

Returns true if strio is at end of file. The stringio must be opened for reading or an IOError will be raised.

static VALUE
strio_eof(VALUE self)
{
    struct StringIO *ptr = readable(self);
    if (ptr->pos < RSTRING_LEN(ptr->string)) return Qfalse;
    return Qtrue;
}
external_encoding → encoding click to toggle source

Returns the Encoding object that represents the encoding of the file. If strio is write mode and no encoding is specified, returns nil.

static VALUE
strio_external_encoding(VALUE self)
{
    return rb_enc_from_encoding(rb_enc_get(StringIO(self)->string));
}
fcntl click to toggle source
#define strio_fcntl strio_unimpl
fileno → nil click to toggle source
#define strio_fileno strio_nil
flush → strio click to toggle source
#define strio_flush strio_self
fsync → 0 click to toggle source
#define strio_fsync strio_0
getbyte → fixnum or nil click to toggle source

See IO#getbyte.

static VALUE
strio_getbyte(VALUE self)
{
    struct StringIO *ptr = readable(self);
    int c;
    if (ptr->pos >= RSTRING_LEN(ptr->string)) {
        return Qnil;
    }
    c = RSTRING_PTR(ptr->string)[ptr->pos++];
    return CHR2FIX(c);
}
getc → string or nil click to toggle source

See IO#getc.

static VALUE
strio_getc(VALUE self)
{
    struct StringIO *ptr = readable(self);
    rb_encoding *enc = rb_enc_get(ptr->string);
    int len;
    char *p;

    if (ptr->pos >= RSTRING_LEN(ptr->string)) {
        return Qnil;
    }
    p = RSTRING_PTR(ptr->string)+ptr->pos;
    len = rb_enc_mbclen(p, RSTRING_END(ptr->string), enc);
    ptr->pos += len;
    return rb_enc_str_new(p, len, rb_enc_get(ptr->string));
}
gets(sep=$/) → string or nil click to toggle source
gets(limit) → string or nil
gets(sep, limit) → string or nil

See IO#gets.

static VALUE
strio_gets(int argc, VALUE *argv, VALUE self)
{
    VALUE str = strio_getline(argc, argv, readable(self));

    rb_lastline_set(str);
    return str;
}
internal_encoding → encoding click to toggle source

Returns the Encoding of the internal string if conversion is specified. Otherwise returns nil.

static VALUE
strio_internal_encoding(VALUE self)
{
     return Qnil;
}
isatty → nil click to toggle source
tty? → nil
#define strio_isatty strio_false
size → integer click to toggle source

Returns the size of the buffer string.

static VALUE
strio_size(VALUE self)
{
    VALUE string = StringIO(self)->string;
    if (NIL_P(string)) {
        rb_raise(rb_eIOError, "not opened");
    }
    return ULONG2NUM(RSTRING_LEN(string));
}
lineno → integer click to toggle source

Returns the current line number in strio. The stringio must be opened for reading. lineno counts the number of times gets is called, rather than the number of newlines encountered. The two values will differ if gets is called with a separator other than newline. See also the $. variable.

static VALUE
strio_get_lineno(VALUE self)
{
    return LONG2NUM(StringIO(self)->lineno);
}
lineno = integer → integer click to toggle source

Manually sets the current line number to the given value. $. is updated only on the next read.

static VALUE
strio_set_lineno(VALUE self, VALUE lineno)
{
    StringIO(self)->lineno = NUM2LONG(lineno);
    return lineno;
}
lines(*args) click to toggle source

This is a deprecated alias for each_line.

static VALUE
strio_lines(int argc, VALUE *argv, VALUE self)
{
    rb_warn("StringIO#lines is deprecated; use #each_line instead");
    if (!rb_block_given_p())
        return rb_enumeratorize(self, ID2SYM(rb_intern("each_line")), argc, argv);
    return strio_each(argc, argv, self);
}
pid → nil click to toggle source
#define strio_pid strio_nil
pos → integer click to toggle source
tell → integer

Returns the current offset (in bytes) of strio.

static VALUE
strio_get_pos(VALUE self)
{
    return LONG2NUM(StringIO(self)->pos);
}
pos = integer → integer click to toggle source

Seeks to the given position (in bytes) in strio.

static VALUE
strio_set_pos(VALUE self, VALUE pos)
{
    struct StringIO *ptr = StringIO(self);
    long p = NUM2LONG(pos);
    if (p < 0) {
        error_inval(0);
    }
    ptr->pos = p;
    return pos;
}
putc(obj) → obj click to toggle source

See IO#putc.

static VALUE
strio_putc(VALUE self, VALUE ch)
{
    struct StringIO *ptr = writable(self);
    VALUE str;

    check_modifiable(ptr);
    if (RB_TYPE_P(ch, T_STRING)) {
        str = rb_str_substr(ch, 0, 1);
    }
    else {
        char c = NUM2CHR(ch);
        str = rb_str_new(&c, 1);
    }
    strio_write(self, str);
    return ch;
}
read([length [, outbuf]]) → string, outbuf, or nil click to toggle source

See IO#read.

static VALUE
strio_read(int argc, VALUE *argv, VALUE self)
{
    struct StringIO *ptr = readable(self);
    VALUE str = Qnil;
    long len;
    int binary = 0;

    switch (argc) {
      case 2:
        str = argv[1];
        if (!NIL_P(str)) {
            StringValue(str);
            rb_str_modify(str);
        }
      case 1:
        if (!NIL_P(argv[0])) {
            len = NUM2LONG(argv[0]);
            if (len < 0) {
                rb_raise(rb_eArgError, "negative length %ld given", len);
            }
            if (len > 0 && ptr->pos >= RSTRING_LEN(ptr->string)) {
                if (!NIL_P(str)) rb_str_resize(str, 0);
                return Qnil;
            }
            binary = 1;
            break;
        }
        /* fall through */
      case 0:
        len = RSTRING_LEN(ptr->string);
        if (len <= ptr->pos) {
            if (NIL_P(str)) {
                str = rb_str_new(0, 0);
            }
            else {
                rb_str_resize(str, 0);
            }
            return str;
        }
        else {
            len -= ptr->pos;
        }
        break;
      default:
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
    }
    if (NIL_P(str)) {
        str = strio_substr(ptr, ptr->pos, len);
        if (binary) rb_enc_associate(str, rb_ascii8bit_encoding());
    }
    else {
        long rest = RSTRING_LEN(ptr->string) - ptr->pos;
        if (len > rest) len = rest;
        rb_str_resize(str, len);
        MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) + ptr->pos, char, len);
        if (binary)
            rb_enc_associate(str, rb_ascii8bit_encoding());
        else
            rb_enc_copy(str, ptr->string);
    }
    ptr->pos += RSTRING_LEN(str);
    return str;
}
readlines(sep=$/) → array click to toggle source
readlines(limit) → array
readlines(sep,limit) → array

See IO#readlines.

static VALUE
strio_readlines(int argc, VALUE *argv, VALUE self)
{
    VALUE ary, line;

    StringIO(self);
    ary = rb_ary_new();
    if (argc > 0 && !NIL_P(argv[argc-1]) && NIL_P(rb_check_string_type(argv[argc-1])) &&
        NUM2LONG(argv[argc-1]) == 0) {
        rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
    }

    while (!NIL_P(line = strio_getline(argc, argv, readable(self)))) {
        rb_ary_push(ary, line);
    }
    return ary;
}
reopen(other_StrIO) → strio click to toggle source
reopen(string, mode) → strio

Reinitializes strio with the given other_StrIO or string and mode (see StringIO#new).

static VALUE
strio_reopen(int argc, VALUE *argv, VALUE self)
{
    rb_io_taint_check(self);
    if (argc == 1 && !RB_TYPE_P(*argv, T_STRING)) {
        return strio_copy(self, *argv);
    }
    strio_init(argc, argv, StringIO(self), self);
    return self;
}
rewind → 0 click to toggle source

Positions strio to the beginning of input, resetting lineno to zero.

static VALUE
strio_rewind(VALUE self)
{
    struct StringIO *ptr = StringIO(self);
    ptr->pos = 0;
    ptr->lineno = 0;
    return INT2FIX(0);
}
seek(amount, whence=SEEK_SET) → 0 click to toggle source

Seeks to a given offset amount in the stream according to the value of whence (see IO#seek).

static VALUE
strio_seek(int argc, VALUE *argv, VALUE self)
{
    VALUE whence;
    struct StringIO *ptr = StringIO(self);
    long offset;

    rb_scan_args(argc, argv, "11", NULL, &whence);
    offset = NUM2LONG(argv[0]);
    if (CLOSED(self)) {
        rb_raise(rb_eIOError, "closed stream");
    }
    switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) {
      case 0:
        break;
      case 1:
        offset += ptr->pos;
        break;
      case 2:
        offset += RSTRING_LEN(ptr->string);
        break;
      default:
        error_inval("invalid whence");
    }
    if (offset < 0) {
        error_inval(0);
    }
    ptr->pos = offset;
    return INT2FIX(0);
}
set_encoding(ext_enc, [int_enc[, opt]]) → strio click to toggle source

Specify the encoding of the StringIO as ext_enc. Use the default external encoding if ext_enc is nil. 2nd argument int_enc and optional hash opt argument are ignored; they are for API compatibility to IO.

static VALUE
strio_set_encoding(int argc, VALUE *argv, VALUE self)
{
    rb_encoding* enc;
    VALUE str = StringIO(self)->string;
    VALUE ext_enc, int_enc, opt;

    argc = rb_scan_args(argc, argv, "11:", &ext_enc, &int_enc, &opt);

    if (NIL_P(ext_enc)) {
        enc = rb_default_external_encoding();
    }
    else {
        enc = rb_to_encoding(ext_enc);
    }
    rb_enc_associate(str, enc);
    return self;
}
size → integer click to toggle source

Returns the size of the buffer string.

static VALUE
strio_size(VALUE self)
{
    VALUE string = StringIO(self)->string;
    if (NIL_P(string)) {
        rb_raise(rb_eIOError, "not opened");
    }
    return ULONG2NUM(RSTRING_LEN(string));
}
string → string click to toggle source

Returns underlying String object, the subject of IO.

static VALUE
strio_get_string(VALUE self)
{
    return StringIO(self)->string;
}
string = string → string click to toggle source

Changes underlying String object, the subject of IO.

static VALUE
strio_set_string(VALUE self, VALUE string)
{
    struct StringIO *ptr = StringIO(self);

    rb_io_taint_check(self);
    ptr->flags &= ~FMODE_READWRITE;
    StringValue(string);
    ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
    ptr->pos = 0;
    ptr->lineno = 0;
    return ptr->string = string;
}
sync → true click to toggle source

Returns true always.

static VALUE
strio_get_sync(VALUE self)
{
    StringIO(self);
    return Qtrue;
}
sync = boolean → boolean click to toggle source
#define strio_set_sync strio_first
pos → integer click to toggle source
tell → integer

Returns the current offset (in bytes) of strio.

static VALUE
strio_get_pos(VALUE self)
{
    return LONG2NUM(StringIO(self)->pos);
}
truncate(integer) → 0 click to toggle source

Truncates the buffer string to at most integer bytes. The strio must be opened for writing.

static VALUE
strio_truncate(VALUE self, VALUE len)
{
    VALUE string = writable(self)->string;
    long l = NUM2LONG(len);
    long plen = RSTRING_LEN(string);
    if (l < 0) {
        error_inval("negative length");
    }
    rb_str_resize(string, l);
    if (plen < l) {
        MEMZERO(RSTRING_PTR(string) + plen, char, l - plen);
    }
    return len;
}
isatty → nil click to toggle source
tty? → nil
#define strio_isatty strio_false
ungetbyte(fixnum) → nil click to toggle source

See IO#ungetbyte

static VALUE
strio_ungetbyte(VALUE self, VALUE c)
{
    struct StringIO *ptr = readable(self);
    char buf[1], *cp = buf;
    long pos = ptr->pos, cl = 1;
    VALUE str = ptr->string;

    if (NIL_P(c)) return Qnil;
    if (FIXNUM_P(c)) {
        buf[0] = (char)FIX2INT(c);
    }
    else {
        SafeStringValue(c);
        cp = RSTRING_PTR(c);
        cl = RSTRING_LEN(c);
        if (cl == 0) return Qnil;
    }
    check_modifiable(ptr);
    rb_str_modify(str);
    if (cl > pos) {
        char *s;
        long rest = RSTRING_LEN(str) - pos;
        rb_str_resize(str, rest + cl);
        s = RSTRING_PTR(str);
        memmove(s + cl, s + pos, rest);
        pos = 0;
    }
    else {
        pos -= cl;
    }
    memcpy(RSTRING_PTR(str) + pos, cp, cl);
    ptr->pos = pos;
    RB_GC_GUARD(c);
    return Qnil;
}
ungetc(string) → nil click to toggle source

Pushes back one character (passed as a parameter) onto strio such that a subsequent buffered read will return it. There is no limitation for multiple pushbacks including pushing back behind the beginning of the buffer string.

static VALUE
strio_ungetc(VALUE self, VALUE c)
{
    struct StringIO *ptr = readable(self);
    long lpos, clen;
    char *p, *pend;
    rb_encoding *enc, *enc2;

    if (NIL_P(c)) return Qnil;
    check_modifiable(ptr);
    if (FIXNUM_P(c)) {
        int cc = FIX2INT(c);
        char buf[16];

        enc = rb_enc_get(ptr->string);
        rb_enc_mbcput(cc, buf, enc);
        c = rb_enc_str_new(buf, rb_enc_codelen(cc, enc), enc);
    }
    else {
        SafeStringValue(c);
        enc = rb_enc_get(ptr->string);
        enc2 = rb_enc_get(c);
        if (enc != enc2 && enc != rb_ascii8bit_encoding()) {
            c = rb_str_conv_enc(c, enc2, enc);
        }
    }
    if (RSTRING_LEN(ptr->string) < ptr->pos) {
        long len = RSTRING_LEN(ptr->string);
        rb_str_resize(ptr->string, ptr->pos - 1);
        memset(RSTRING_PTR(ptr->string) + len, 0, ptr->pos - len - 1);
        rb_str_concat(ptr->string, c);
        ptr->pos--;
    }
    else {
        /* get logical position */
        lpos = 0; p = RSTRING_PTR(ptr->string); pend = p + ptr->pos;
        for (;;) {
            clen = rb_enc_mbclen(p, pend, enc);
            if (p+clen >= pend) break;
            p += clen;
            lpos++;
        }
        clen = p - RSTRING_PTR(ptr->string);
        rb_str_update(ptr->string, lpos, ptr->pos ? 1 : 0, c);
        ptr->pos = clen;
    }

    return Qnil;
}
write(string) → integer click to toggle source
syswrite(string) → integer

Appends the given string to the underlying buffer string of strio. The stream must be opened for writing. If the argument is not a string, it will be converted to a string using to_s. Returns the number of bytes written. See IO#write.

static VALUE
strio_write(VALUE self, VALUE str)
{
    struct StringIO *ptr = writable(self);
    long len, olen;
    rb_encoding *enc, *enc2;

    if (!RB_TYPE_P(str, T_STRING))
        str = rb_obj_as_string(str);
    enc = rb_enc_get(ptr->string);
    enc2 = rb_enc_get(str);
    if (enc != enc2 && enc != rb_ascii8bit_encoding()) {
        str = rb_str_conv_enc(str, enc2, enc);
    }
    len = RSTRING_LEN(str);
    if (len == 0) return INT2FIX(0);
    check_modifiable(ptr);
    olen = RSTRING_LEN(ptr->string);
    if (ptr->flags & FMODE_APPEND) {
        ptr->pos = olen;
    }
    if (ptr->pos == olen) {
        if (enc2 == rb_ascii8bit_encoding()) {
            rb_enc_str_buf_cat(ptr->string, RSTRING_PTR(str), len, enc);
            OBJ_INFECT(ptr->string, str);
        }
        else {
            rb_str_buf_append(ptr->string, str);
        }
    }
    else {
        strio_extend(ptr, ptr->pos, len);
        memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len);
        OBJ_INFECT(ptr->string, str);
    }
    OBJ_INFECT(ptr->string, self);
    RB_GC_GUARD(str);
    ptr->pos += len;
    return LONG2NUM(len);
}


class StringScanner - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class StringScanner

StringScanner provides for lexical scanning operations on a String. Here is an example of its usage:

s = StringScanner.new('This is an example string')
s.eos?               # -> false

p s.scan(/\w+/)      # -> "This"
p s.scan(/\w+/)      # -> nil
p s.scan(/\s+/)      # -> " "
p s.scan(/\s+/)      # -> nil
p s.scan(/\w+/)      # -> "is"
s.eos?               # -> false

p s.scan(/\s+/)      # -> " "
p s.scan(/\w+/)      # -> "an"
p s.scan(/\s+/)      # -> " "
p s.scan(/\w+/)      # -> "example"
p s.scan(/\s+/)      # -> " "
p s.scan(/\w+/)      # -> "string"
s.eos?               # -> true

p s.scan(/\s+/)      # -> nil
p s.scan(/\w+/)      # -> nil

Scanning a string means remembering the position of a scan pointer, which is just an index. The point of scanning is to move forward a bit at a time, so matches are sought after the scan pointer; usually immediately after it.

Given the string “test string”, here are the pertinent scan pointer positions:

  t e s t   s t r i n g
0 1 2 ...             1
                      0

When you scan for a pattern (a regular expression), the match must occur at the character after the scan pointer. If you use scan_until, then the match can occur anywhere after the scan pointer. In both cases, the scan pointer moves just beyond the last character of the match, ready to scan again from the next character onwards. This is demonstrated by the example above.

Method Categories

There are other methods besides the plain scanners. You can look ahead in the string without actually scanning. You can access the most recent match. You can modify the string being scanned, reset or terminate the scanner, find out or change the position of the scan pointer, skip ahead, and so on.

Advancing the Scan Pointer

  • getch

  • get_byte

  • scan

  • scan_until

  • skip

  • skip_until

Looking Ahead

  • check

  • check_until

  • exist?

  • match?

  • peek

Finding Where we Are

  • beginning_of_line? (bol?)

  • eos?

  • rest?

  • rest_size

  • pos

Setting Where we Are

  • reset

  • terminate

  • pos=

Match Data

  • matched

  • matched?

  • matched_size

  • pre_match

  • post_match

Miscellaneous

  • <<

  • concat

  • string

  • string=

  • unscan

There are aliases to several of the methods.

In Files

  • ext/strscan/strscan.c

Parent

Object

Public Class Methods

must_C_version click to toggle source

This method is defined for backward compatibility.

static VALUE
strscan_s_mustc(VALUE self)
{
    return self;
}
new(string, dup = false) click to toggle source

Creates a new StringScanner object to scan over the given string. dup argument is obsolete and not used now.

static VALUE
strscan_initialize(int argc, VALUE *argv, VALUE self)
{
    struct strscanner *p;
    VALUE str, need_dup;

    p = check_strscan(self);
    rb_scan_args(argc, argv, "11", &str, &need_dup);
    StringValue(str);
    p->str = str;

    return self;
}

Public Instance Methods

concat(str) click to toggle source
<<(str)

Appends str to the string being scanned. This method does not affect scan pointer.

s = StringScanner.new("Fri Dec 12 1975 14:39")
s.scan(/Fri /)
s << " +1000 GMT"
s.string            # -> "Fri Dec 12 1975 14:39 +1000 GMT"
s.scan(/Dec/)       # -> "Dec"
static VALUE
strscan_concat(VALUE self, VALUE str)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    StringValue(str);
    rb_str_append(p->str, str);
    return self;
}
[](n) click to toggle source

Return the n-th subgroup in the most recent match.

s = StringScanner.new("Fri Dec 12 1975 14:39")
s.scan(/(\w+) (\w+) (\d+) /)       # -> "Fri Dec 12 "
s[0]                               # -> "Fri Dec 12 "
s[1]                               # -> "Fri"
s[2]                               # -> "Dec"
s[3]                               # -> "12"
s.post_match                       # -> "1975 14:39"
s.pre_match                        # -> ""
static VALUE
strscan_aref(VALUE self, VALUE idx)
{
    struct strscanner *p;
    long i;

    GET_SCANNER(self, p);
    if (! MATCHED_P(p))        return Qnil;

    i = NUM2LONG(idx);
    if (i < 0)
        i += p->regs.num_regs;
    if (i < 0)                 return Qnil;
    if (i >= p->regs.num_regs) return Qnil;
    if (p->regs.beg[i] == -1)  return Qnil;

    return extract_range(p, p->prev + p->regs.beg[i],
                            p->prev + p->regs.end[i]);
}
beginning_of_line?() click to toggle source

Returns true iff the scan pointer is at the beginning of the line.

s = StringScanner.new("test\ntest\n")
s.bol?           # => true
s.scan(/te/)
s.bol?           # => false
s.scan(/st\n/)
s.bol?           # => true
s.terminate
s.bol?           # => true

static VALUE
strscan_bol_p(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    if (CURPTR(p) > S_PEND(p)) return Qnil;
    if (p->curr == 0) return Qtrue;
    return (*(CURPTR(p) - 1) == '\n') ? Qtrue : Qfalse;
}
charpos() click to toggle source

Returns the character position of the scan pointer. In the 'reset' position, this value is zero. In the 'terminated' position (i.e. the string is exhausted), this value is the size of the string.

In short, it's a 0-based index into the string.

s = StringScanner.new("abcädeföghi")
s.charpos           # -> 0
s.scan_until(/ä/)   # -> "abcä"
s.pos               # -> 5
s.charpos           # -> 4
static VALUE
strscan_get_charpos(VALUE self)
{
    struct strscanner *p;
    VALUE substr;

    GET_SCANNER(self, p);

    substr = rb_funcall(p->str, id_byteslice, 2, INT2FIX(0), INT2NUM(p->curr));

    return rb_str_length(substr);
}
check(pattern) click to toggle source

This returns the value that scan would return, without advancing the scan pointer. The match register is affected, though.

s = StringScanner.new("Fri Dec 12 1975 14:39")
s.check /Fri/               # -> "Fri"
s.pos                       # -> 0
s.matched                   # -> "Fri"
s.check /12/                # -> nil
s.matched                   # -> nil

Mnemonic: it “checks” to see whether a scan will return a value.

static VALUE
strscan_check(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 0, 1, 1);
}
check_until(pattern) click to toggle source

This returns the value that scan_until would return, without advancing the scan pointer. The match register is affected, though.

s = StringScanner.new("Fri Dec 12 1975 14:39")
s.check_until /12/          # -> "Fri Dec 12"
s.pos                       # -> 0
s.matched                   # -> 12

Mnemonic: it “checks” to see whether a scan_until will return a value.

static VALUE
strscan_check_until(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 0, 1, 0);
}
clear() click to toggle source

Equivalent to terminate. This method is obsolete; use terminate instead.

static VALUE
strscan_clear(VALUE self)
{
    rb_warning("StringScanner#clear is obsolete; use #terminate instead");
    return strscan_terminate(self);
}
concat(str) click to toggle source
<<(str)

Appends str to the string being scanned. This method does not affect scan pointer.

s = StringScanner.new("Fri Dec 12 1975 14:39")
s.scan(/Fri /)
s << " +1000 GMT"
s.string            # -> "Fri Dec 12 1975 14:39 +1000 GMT"
s.scan(/Dec/)       # -> "Dec"
static VALUE
strscan_concat(VALUE self, VALUE str)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    StringValue(str);
    rb_str_append(p->str, str);
    return self;
}
empty?() click to toggle source

Equivalent to eos?. This method is obsolete, use eos? instead.

static VALUE
strscan_empty_p(VALUE self)
{
    rb_warning("StringScanner#empty? is obsolete; use #eos? instead");
    return strscan_eos_p(self);
}
eos?() click to toggle source

Returns true if the scan pointer is at the end of the string.

s = StringScanner.new('test string')
p s.eos?          # => false
s.scan(/test/)
p s.eos?          # => false
s.terminate
p s.eos?          # => true

static VALUE
strscan_eos_p(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    return EOS_P(p) ? Qtrue : Qfalse;
}
exist?(pattern) click to toggle source

Looks ahead to see if the pattern exists anywhere in the string, without advancing the scan pointer. This predicates whether a scan_until will return a value.

s = StringScanner.new('test string')
s.exist? /s/            # -> 3
s.scan /test/           # -> "test"
s.exist? /s/            # -> 2
s.exist? /e/            # -> nil
static VALUE
strscan_exist_p(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 0, 0, 0);
}
get_byte() click to toggle source

Scans one byte and returns it. This method is not multibyte character sensitive. See also: getch.

s = StringScanner.new('ab')
s.get_byte         # => "a"
s.get_byte         # => "b"
s.get_byte         # => nil

$KCODE = 'EUC'
s = StringScanner.new("\2244\2242")
s.get_byte         # => "\244"
s.get_byte         # => "\242"
s.get_byte         # => nil

static VALUE
strscan_get_byte(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    CLEAR_MATCH_STATUS(p);
    if (EOS_P(p))
        return Qnil;

    p->prev = p->curr;
    p->curr++;
    MATCHED(p);
    adjust_registers_to_matched(p);
    return extract_range(p, p->prev + p->regs.beg[0],
                            p->prev + p->regs.end[0]);
}
getbyte() click to toggle source

Equivalent to get_byte. This method is obsolete; use get_byte instead.

static VALUE
strscan_getbyte(VALUE self)
{
    rb_warning("StringScanner#getbyte is obsolete; use #get_byte instead");
    return strscan_get_byte(self);
}
getch() click to toggle source

Scans one character and returns it. This method is multibyte character sensitive.

s = StringScanner.new("ab")
s.getch           # => "a"
s.getch           # => "b"
s.getch           # => nil

$KCODE = 'EUC'
s = StringScanner.new("\2244\2242")
s.getch           # => "\244\242"   # Japanese hira-kana "A" in EUC-JP
s.getch           # => nil

static VALUE
strscan_getch(VALUE self)
{
    struct strscanner *p;
    long len;

    GET_SCANNER(self, p);
    CLEAR_MATCH_STATUS(p);
    if (EOS_P(p))
        return Qnil;

    len = rb_enc_mbclen(CURPTR(p), S_PEND(p), rb_enc_get(p->str));
    if (p->curr + len > S_LEN(p)) {
        len = S_LEN(p) - p->curr;
    }
    p->prev = p->curr;
    p->curr += len;
    MATCHED(p);
    adjust_registers_to_matched(p);
    return extract_range(p, p->prev + p->regs.beg[0],
                            p->prev + p->regs.end[0]);
}
inspect() click to toggle source

Returns a string that represents the StringScanner object, showing:

  • the current position

  • the size of the string

  • the characters surrounding the scan pointer

    s = ::new(“Fri Dec 12 1975 14:39”) s.inspect # -> '#<StringScanner 0/21 @ “Fri D…”>' s.scan_until /12/ # -> “Fri Dec 12” s.inspect # -> '#<StringScanner 10/21 “…ec 12” @ “ 1975…”>'

static VALUE
strscan_inspect(VALUE self)
{
    struct strscanner *p;
    VALUE a, b;

    p = check_strscan(self);
    if (NIL_P(p->str)) {
        a = rb_sprintf("#<%"PRIsVALUE" (uninitialized)>", rb_obj_class(self));
        return infect(a, p);
    }
    if (EOS_P(p)) {
        a = rb_sprintf("#<%"PRIsVALUE" fin>", rb_obj_class(self));
        return infect(a, p);
    }
    if (p->curr == 0) {
        b = inspect2(p);
        a = rb_sprintf("#<%"PRIsVALUE" %ld/%ld @ %"PRIsVALUE">",
                       rb_obj_class(self),
                       p->curr, S_LEN(p),
                       b);
        return infect(a, p);
    }
    a = inspect1(p);
    b = inspect2(p);
    a = rb_sprintf("#<%"PRIsVALUE" %ld/%ld %"PRIsVALUE" @ %"PRIsVALUE">",
                   rb_obj_class(self),
                   p->curr, S_LEN(p),
                   a, b);
    return infect(a, p);
}
match?(pattern) click to toggle source

Tests whether the given pattern is matched from the current scan pointer. Returns the length of the match, or nil. The scan pointer is not advanced.

s = StringScanner.new('test string')
p s.match?(/\w+/)   # -> 4
p s.match?(/\w+/)   # -> 4
p s.match?(/\s+/)   # -> nil
static VALUE
strscan_match_p(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 0, 0, 1);
}
matched() click to toggle source

Returns the last matched string.

s = StringScanner.new('test string')
s.match?(/\w+/)     # -> 4
s.matched           # -> "test"
static VALUE
strscan_matched(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    if (! MATCHED_P(p)) return Qnil;
    return extract_range(p, p->prev + p->regs.beg[0],
                            p->prev + p->regs.end[0]);
}
matched?() click to toggle source

Returns true iff the last match was successful.

s = StringScanner.new('test string')
s.match?(/\w+/)     # => 4
s.matched?          # => true
s.match?(/\d+/)     # => nil
s.matched?          # => false

static VALUE
strscan_matched_p(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    return MATCHED_P(p) ? Qtrue : Qfalse;
}
matched_size() click to toggle source

Returns the size of the most recent match (see matched), or nil if there was no recent match.

s = StringScanner.new('test string')
s.check /\w+/           # -> "test"
s.matched_size          # -> 4
s.check /\d+/           # -> nil
s.matched_size          # -> nil
static VALUE
strscan_matched_size(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    if (! MATCHED_P(p)) return Qnil;
    return INT2NUM(p->regs.end[0] - p->regs.beg[0]);
}
peek(len) click to toggle source

Extracts a string corresponding to string[pos,len], without advancing the scan pointer.

s = StringScanner.new('test string')
s.peek(7)          # => "test st"
s.peek(7)          # => "test st"

static VALUE
strscan_peek(VALUE self, VALUE vlen)
{
    struct strscanner *p;
    long len;

    GET_SCANNER(self, p);

    len = NUM2LONG(vlen);
    if (EOS_P(p))
        return infect(str_new(p, "", 0), p);

    if (p->curr + len > S_LEN(p))
        len = S_LEN(p) - p->curr;
    return extract_beg_len(p, p->curr, len);
}
peep(p1) click to toggle source

Equivalent to peek. This method is obsolete; use peek instead.

static VALUE
strscan_peep(VALUE self, VALUE vlen)
{
    rb_warning("StringScanner#peep is obsolete; use #peek instead");
    return strscan_peek(self, vlen);
}
pointer() click to toggle source

Returns the byte position of the scan pointer. In the 'reset' position, this value is zero. In the 'terminated' position (i.e. the string is exhausted), this value is the bytesize of the string.

In short, it's a 0-based index into bytes of the string.

s = StringScanner.new('test string')
s.pos               # -> 0
s.scan_until /str/  # -> "test str"
s.pos               # -> 8
s.terminate         # -> #<StringScanner fin>
s.pos               # -> 11
static VALUE
strscan_get_pos(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    return INT2FIX(p->curr);
}
pos=(n) click to toggle source

Set the byte position of the scan pointer.

s = StringScanner.new('test string')
s.pos = 7            # -> 7
s.rest               # -> "ring"
static VALUE
strscan_set_pos(VALUE self, VALUE v)
{
    struct strscanner *p;
    long i;

    GET_SCANNER(self, p);
    i = NUM2INT(v);
    if (i < 0) i += S_LEN(p);
    if (i < 0) rb_raise(rb_eRangeError, "index out of range");
    if (i > S_LEN(p)) rb_raise(rb_eRangeError, "index out of range");
    p->curr = i;
    return INT2NUM(i);
}
pos() click to toggle source

Returns the byte position of the scan pointer. In the 'reset' position, this value is zero. In the 'terminated' position (i.e. the string is exhausted), this value is the bytesize of the string.

In short, it's a 0-based index into bytes of the string.

s = StringScanner.new('test string')
s.pos               # -> 0
s.scan_until /str/  # -> "test str"
s.pos               # -> 8
s.terminate         # -> #<StringScanner fin>
s.pos               # -> 11
static VALUE
strscan_get_pos(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    return INT2FIX(p->curr);
}
pos=(n) click to toggle source

Set the byte position of the scan pointer.

s = StringScanner.new('test string')
s.pos = 7            # -> 7
s.rest               # -> "ring"
static VALUE
strscan_set_pos(VALUE self, VALUE v)
{
    struct strscanner *p;
    long i;

    GET_SCANNER(self, p);
    i = NUM2INT(v);
    if (i < 0) i += S_LEN(p);
    if (i < 0) rb_raise(rb_eRangeError, "index out of range");
    if (i > S_LEN(p)) rb_raise(rb_eRangeError, "index out of range");
    p->curr = i;
    return INT2NUM(i);
}
post_match() click to toggle source

Return the post-match (in the regular expression sense) of the last scan.

s = StringScanner.new('test string')
s.scan(/\w+/)           # -> "test"
s.scan(/\s+/)           # -> " "
s.pre_match             # -> "test"
s.post_match            # -> "string"
static VALUE
strscan_post_match(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    if (! MATCHED_P(p)) return Qnil;
    return extract_range(p, p->prev + p->regs.end[0], S_LEN(p));
}
pre_match() click to toggle source

Return the pre-match (in the regular expression sense) of the last scan.

s = StringScanner.new('test string')
s.scan(/\w+/)           # -> "test"
s.scan(/\s+/)           # -> " "
s.pre_match             # -> "test"
s.post_match            # -> "string"
static VALUE
strscan_pre_match(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    if (! MATCHED_P(p)) return Qnil;
    return extract_range(p, 0, p->prev + p->regs.beg[0]);
}
reset() click to toggle source

Reset the scan pointer (index 0) and clear matching data.

static VALUE
strscan_reset(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    p->curr = 0;
    CLEAR_MATCH_STATUS(p);
    return self;
}
rest() click to toggle source

Returns the “rest” of the string (i.e. everything after the scan pointer). If there is no more data (eos? = true), it returns "".

static VALUE
strscan_rest(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    if (EOS_P(p)) {
        return infect(str_new(p, "", 0), p);
    }
    return extract_range(p, p->curr, S_LEN(p));
}
rest?() click to toggle source

Returns true iff there is more data in the string. See eos?. This method is obsolete; use eos? instead.

s = StringScanner.new('test string')
s.eos?              # These two
s.rest?             # are opposites.
static VALUE
strscan_rest_p(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    return EOS_P(p) ? Qfalse : Qtrue;
}
rest_size() click to toggle source

s.rest_size is equivalent to s.rest.size.

static VALUE
strscan_rest_size(VALUE self)
{
    struct strscanner *p;
    long i;

    GET_SCANNER(self, p);
    if (EOS_P(p)) {
        return INT2FIX(0);
    }
    i = S_LEN(p) - p->curr;
    return INT2FIX(i);
}
restsize() click to toggle source

s.restsize is equivalent to s.rest_size. This method is obsolete; use rest_size instead.

static VALUE
strscan_restsize(VALUE self)
{
    rb_warning("StringScanner#restsize is obsolete; use #rest_size instead");
    return strscan_rest_size(self);
}
scan(pattern) → String click to toggle source

Tries to match with pattern at the current position. If there's a match, the scanner advances the “scan pointer” and returns the matched string. Otherwise, the scanner returns nil.

s = StringScanner.new('test string')
p s.scan(/\w+/)   # -> "test"
p s.scan(/\w+/)   # -> nil
p s.scan(/\s+/)   # -> " "
p s.scan(/\w+/)   # -> "string"
p s.scan(/./)     # -> nil
static VALUE
strscan_scan(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 1, 1, 1);
}
scan_full(pattern, advance_pointer_p, return_string_p) click to toggle source

Tests whether the given pattern is matched from the current scan pointer. Advances the scan pointer if advance_pointer_p is true. Returns the matched string if return_string_p is true. The match register is affected.

“full” means “scan with full parameters”.

static VALUE
strscan_scan_full(VALUE self, VALUE re, VALUE s, VALUE f)
{
    return strscan_do_scan(self, re, RTEST(s), RTEST(f), 1);
}
scan_until(pattern) click to toggle source

Scans the string until the pattern is matched. Returns the substring up to and including the end of the match, advancing the scan pointer to that location. If there is no match, nil is returned.

s = StringScanner.new("Fri Dec 12 1975 14:39")
s.scan_until(/1/)        # -> "Fri Dec 1"
s.pre_match              # -> "Fri Dec "
s.scan_until(/XYZ/)      # -> nil
static VALUE
strscan_scan_until(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 1, 1, 0);
}
search_full(pattern, advance_pointer_p, return_string_p) click to toggle source

Scans the string until the pattern is matched. Advances the scan pointer if advance_pointer_p, otherwise not. Returns the matched string if return_string_p is true, otherwise returns the number of bytes advanced. This method does affect the match register.

static VALUE
strscan_search_full(VALUE self, VALUE re, VALUE s, VALUE f)
{
    return strscan_do_scan(self, re, RTEST(s), RTEST(f), 0);
}
skip(pattern) click to toggle source

Attempts to skip over the given pattern beginning with the scan pointer. If it matches, the scan pointer is advanced to the end of the match, and the length of the match is returned. Otherwise, nil is returned.

It's similar to scan, but without returning the matched string.

s = StringScanner.new('test string')
p s.skip(/\w+/)   # -> 4
p s.skip(/\w+/)   # -> nil
p s.skip(/\s+/)   # -> 1
p s.skip(/\w+/)   # -> 6
p s.skip(/./)     # -> nil
static VALUE
strscan_skip(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 1, 0, 1);
}
skip_until(pattern) click to toggle source

Advances the scan pointer until pattern is matched and consumed. Returns the number of bytes advanced, or nil if no match was found.

Look ahead to match pattern, and advance the scan pointer to the end of the match. Return the number of characters advanced, or nil if the match was unsuccessful.

It's similar to scan_until, but without returning the intervening string.

s = StringScanner.new("Fri Dec 12 1975 14:39")
s.skip_until /12/           # -> 10
s                           #
static VALUE
strscan_skip_until(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 1, 0, 0);
}
string() click to toggle source

Returns the string being scanned.

static VALUE
strscan_get_string(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    return p->str;
}
string=(str) click to toggle source

Changes the string being scanned to str and resets the scanner. Returns str.

static VALUE
strscan_set_string(VALUE self, VALUE str)
{
    struct strscanner *p = check_strscan(self);

    StringValue(str);
    p->str = str;
    p->curr = 0;
    CLEAR_MATCH_STATUS(p);
    return str;
}
terminate click to toggle source
clear

Set the scan pointer to the end of the string and clear matching data.

static VALUE
strscan_terminate(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    p->curr = S_LEN(p);
    CLEAR_MATCH_STATUS(p);
    return self;
}
unscan() click to toggle source

Set the scan pointer to the previous position. Only one previous position is remembered, and it changes with each scanning operation.

s = StringScanner.new('test string')
s.scan(/\w+/)        # => "test"
s.unscan
s.scan(/../)         # => "te"
s.scan(/\d/)         # => nil
s.unscan             # ScanError: unscan failed: previous match record not exist

static VALUE
strscan_unscan(VALUE self)
{
    struct strscanner *p;

    GET_SCANNER(self, p);
    if (! MATCHED_P(p))
        rb_raise(ScanError, "unscan failed: previous match record not exist");
    p->curr = p->prev;
    CLEAR_MATCH_STATUS(p);
    return self;
}


class StringScanner::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class StringScanner::Error

In Files

  • ext/strscan/strscan.c

Parent

StandardError


class Struct - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Struct

Struct serialization/deserialization

In Files

  • lib/pp.rb
  • ext/json/lib/json/add/struct.rb

Parent

Object

Public Class Methods

json_create(object) click to toggle source

Deserializes JSON string by constructing new Struct object with values v serialized by to_json.

# File ext/json/lib/json/add/struct.rb, line 10
def self.json_create(object)
  new(*object['v'])
end

Public Instance Methods

as_json(*) click to toggle source

Returns a hash, that will be turned into a JSON object and represent this object.

# File ext/json/lib/json/add/struct.rb, line 16
def as_json(*)
  klass = self.class.name
  klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
  {
    JSON.create_id => klass,
    'v'            => values,
  }
end
pretty_print(q) click to toggle source
# File lib/pp.rb, line 362
def pretty_print(q)
  q.group(1, sprintf("#<struct %s", PP.mcall(self, Kernel, :class).name), '>') {
    q.seplist(PP.mcall(self, Struct, :members), lambda { q.text "," }) {|member|
      q.breakable
      q.text member.to_s
      q.text '='
      q.group(1) {
        q.breakable ''
        q.pp self[member]
      }
    }
  }
end
pretty_print_cycle(q) click to toggle source
# File lib/pp.rb, line 376
def pretty_print_cycle(q)
  q.text sprintf("#<struct %s:...>", PP.mcall(self, Kernel, :class).name)
end
to_json(*args) click to toggle source

Stores class name (Struct) with Struct values v as a JSON string. Only named structs are supported.

# File ext/json/lib/json/add/struct.rb, line 27
def to_json(*args)
  as_json.to_json(*args)
end


class Symbol - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Symbol

Symbol serialization/deserialization

In Files

  • lib/rexml/xpath_parser.rb
  • ext/json/lib/json/add/symbol.rb

Parent

Object

Public Class Methods

json_create(o) click to toggle source

Deserializes JSON string by converting the string value stored in the object to a Symbol

# File ext/json/lib/json/add/symbol.rb, line 22
def self.json_create(o)
  o['s'].to_sym
end

Public Instance Methods

as_json(*) click to toggle source

Returns a hash, that will be turned into a JSON object and represent this object.

# File ext/json/lib/json/add/symbol.rb, line 9
def as_json(*)
  {
    JSON.create_id => self.class.name,
    's'            => to_s,
  }
end
dclone() click to toggle source

provides a unified clone operation, for REXML::XPathParser to use across multiple Object types

# File lib/rexml/xpath_parser.rb, line 17
def dclone ; self ; end
to_json(*a) click to toggle source

Stores class name (Symbol) with String representation of Symbol as a JSON string.

# File ext/json/lib/json/add/symbol.rb, line 17
def to_json(*a)
  as_json.to_json(*a)
end


class Sync_m::Err - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Sync_m::Err

exceptions

In Files

  • lib/sync.rb

Parent

StandardError

Public Class Methods

Fail(*opt) click to toggle source
# File lib/sync.rb, line 55
def Err.Fail(*opt)
  fail self, sprintf(self::Message, *opt)
end


class Sync_m::Err::LockModeFailer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Sync_m::Err::LockModeFailer

In Files

  • lib/sync.rb

Parent

Sync_m::Err

Constants

Message

Public Class Methods

Fail(mode) click to toggle source
# File lib/sync.rb, line 68
def LockModeFailer.Fail(mode)
  if mode.id2name
    mode = id2name
  end
  super(mode)
end


class Sync_m::Err::UnknownLocker - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Sync_m::Err::UnknownLocker

In Files

  • lib/sync.rb

Parent

Sync_m::Err

Constants

Message

Public Class Methods

Fail(th) click to toggle source
# File lib/sync.rb, line 61
def UnknownLocker.Fail(th)
  super(th.inspect)
end


module Sys - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Sys

Sys provides a number of file manipulation tools for the convenience of writing Rakefiles. All commands in this module will announce their activity on standard output if the $verbose flag is set ($verbose = true is the default). You can control this by globally setting $verbose or by using the verbose and quiet methods.

Sys has been deprecated in favor of the FileUtils module available in Ruby 1.8.

In Files

  • lib/rake/contrib/sys.rb

Constants

RUBY

Public Instance Methods

copy(file_name, dest_file) click to toggle source

Copy a single file from file_name to dest_file.

# File lib/rake/contrib/sys.rb, line 48
def copy(file_name, dest_file)
  log "Copying file #{file_name} to #{dest_file}"
  File.copy(file_name, dest_file)
end
copy_files(wildcard, dest_dir) click to toggle source

Copy all files matching wildcard into the directory dest_dir.

# File lib/rake/contrib/sys.rb, line 54
def copy_files(wildcard, dest_dir)
  for_matching_files(wildcard, dest_dir) { |from, to| copy(from, to) }
end
delete(*wildcards) click to toggle source

Remove all files matching wildcard. If a matching file is a directory, it must be empty to be removed. used delete_all to recursively delete directories.

# File lib/rake/contrib/sys.rb, line 83
def delete(*wildcards)
  wildcards.each do |wildcard|
    FileList.glob(wildcard).each do |fn|
      if File.directory?(fn)
        log "Deleting directory #{fn}"
        Dir.delete(fn)
      else
        log "Deleting file #{fn}"
        File.delete(fn)
      end
    end
  end
end
delete_all(*wildcards) click to toggle source

Recursively delete all files and directories matching wildcard.

# File lib/rake/contrib/sys.rb, line 98
def delete_all(*wildcards)
  wildcards.each do |wildcard|
    FileList.glob(wildcard).each do |fn|
      next if ! File.exist?(fn)
      if File.directory?(fn)
        FileList.glob("#{fn}/*").each do |subfn|
          next if subfn=='.' || subfn=='..'
          delete_all(subfn)
        end
        log "Deleting directory #{fn}"
        Dir.delete(fn)
      else
        log "Deleting file #{fn}"
        File.delete(fn)
      end
    end
  end
end
for_files(*wildcards) { |fn| ... } click to toggle source

Perform a block with each file matching a set of wildcards.

# File lib/rake/contrib/sys.rb, line 163
def for_files(*wildcards)
  wildcards.each do |wildcard|
    FileList.glob(wildcard).each do |fn|
      yield(fn)
    end
  end
end
indir(dir) { || ... } click to toggle source

Make dir the current working directory for the duration of executing the given block.

# File lib/rake/contrib/sys.rb, line 127
def indir(dir)
  olddir = Dir.pwd
  Dir.chdir(dir)
  yield
ensure
  Dir.chdir(olddir)
end
install(wildcard, dest_dir, mode) click to toggle source

Install all the files matching wildcard into the dest_dir directory. The permission mode is set to mode.

# File lib/rake/contrib/sys.rb, line 30
def install(wildcard, dest_dir, mode)
  FileList.glob(wildcard).each do |fn|
    File.install(fn, dest_dir, mode, $verbose)
  end
end
link(file_name, dest_file) click to toggle source

Link file_name to dest_file.

# File lib/rake/contrib/sys.rb, line 59
def link(file_name, dest_file)
  log "Linking file #{file_name} to #{dest_file}"
  File.link(file_name, dest_file)
end
link_files(wildcard, dest_dir) click to toggle source

Link all files matching wildcard into the directory dest_dir.

# File lib/rake/contrib/sys.rb, line 65
def link_files(wildcard, dest_dir)
  for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) }
end
log(msg) click to toggle source

Write a message to standard error if $verbose is enabled.

# File lib/rake/contrib/sys.rb, line 147
def log(msg)
  print "  " if $trace && $verbose
  $stderr.puts msg if $verbose
end
makedirs(*dirs) click to toggle source

Make the directories given in dirs.

# File lib/rake/contrib/sys.rb, line 118
def makedirs(*dirs)
  dirs.each do |fn|
    log "Making directory #{fn}"
    File.makedirs(fn)
  end
end
quiet(&block) click to toggle source

Perform a block with $verbose disabled.

# File lib/rake/contrib/sys.rb, line 153
def quiet(&block)
  with_verbose(false, &block)
end
ruby(*args) click to toggle source

Run a Ruby interpreter with the given arguments.

# File lib/rake/contrib/sys.rb, line 43
def ruby(*args)
  run "#{RUBY} #{args.join(' ')}"
end
run(cmd) click to toggle source

Run the system command cmd.

# File lib/rake/contrib/sys.rb, line 37
def run(cmd)
  log cmd
  system(cmd) or fail "Command Failed: [#{cmd}]"
end
split_all(path) click to toggle source

Split a file path into individual directory names.

For example:

split_all("a/b/c") =>  ['a', 'b', 'c']

# File lib/rake/contrib/sys.rb, line 139
def split_all(path)
  head, tail = File.split(path)
  return [tail] if head == '.' || tail == '/'
  return [head, tail] if head == '/'
  return split_all(head) + [tail]
end
symlink(file_name, dest_file) click to toggle source

Symlink file_name to dest_file.

# File lib/rake/contrib/sys.rb, line 70
def symlink(file_name, dest_file)
  log "Symlinking file #{file_name} to #{dest_file}"
  File.symlink(file_name, dest_file)
end
symlink_files(wildcard, dest_dir) click to toggle source

Symlink all files matching wildcard into the directory dest_dir.

# File lib/rake/contrib/sys.rb, line 76
def symlink_files(wildcard, dest_dir)
  for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) }
end
verbose(&block) click to toggle source

Perform a block with $verbose enabled.

# File lib/rake/contrib/sys.rb, line 158
def verbose(&block)
  with_verbose(true, &block)
end


module Syslog - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Syslog

The syslog package provides a Ruby interface to the POSIX system logging facility.

Syslog messages are typically passed to a central logging daemon. The daemon may filter them; route them into different files (usually found under /var/log); place them in SQL databases; forward them to centralized logging servers via TCP or UDP; or even alert the system administrator via email, pager or text message.

Unlike application-level logging via Logger or Log4r, syslog is designed to allow secure tamper-proof logging.

The syslog protocol is standardized in RFC 5424.

In Files

  • ext/syslog/syslog.c

Public Class Methods

close() click to toggle source

Closes the syslog facility. Raises a runtime exception if it is not open.

static VALUE mSyslog_close(VALUE self)
{
    rb_secure(4);
    if (!syslog_opened) {
        rb_raise(rb_eRuntimeError, "syslog not opened");
    }

    closelog();

    xfree((void *)syslog_ident);
    syslog_ident = NULL;
    syslog_options = syslog_facility = syslog_mask = -1;
    syslog_opened = 0;

    return Qnil;
}
facility() click to toggle source

Returns the facility number used in the last call to open()

static VALUE mSyslog_facility(VALUE self)
{
    return syslog_opened ? INT2NUM(syslog_facility) : Qnil;
}
ident() click to toggle source

Returns the identity string used in the last call to open()

static VALUE mSyslog_ident(VALUE self)
{
    return syslog_opened ? rb_str_new2(syslog_ident) : Qnil;
}
inspect() click to toggle source

Returns an inspect() string summarizing the object state.

static VALUE mSyslog_inspect(VALUE self)
{
    Check_Type(self, T_MODULE);

    if (!syslog_opened)
        return rb_sprintf("<#%"PRIsVALUE": opened=false>", self);

    return rb_sprintf("<#%"PRIsVALUE": opened=true, ident=\"%s\", options=%d, facility=%d, mask=%d>",
                      self,
                      syslog_ident,
                      syslog_options,
                      syslog_facility,
                      syslog_mask);
}
instance() click to toggle source

Returns self, for backward compatibility.

static VALUE mSyslog_instance(VALUE self)
{
    return self;
}
log(priority, format_string, *format_args) click to toggle source

Log a message with the specified priority. Example:

Syslog.log(Syslog::LOG_CRIT, "Out of disk space")
Syslog.log(Syslog::LOG_CRIT, "User %s logged in", ENV['USER'])

The priority levels, in descending order, are:

LOG_EMERG

System is unusable

LOG_ALERT

Action needs to be taken immediately

LOG_CRIT

A critical condition has occurred

LOG_ERR

An error occurred

LOG_WARNING

Warning of a possible problem

LOG_NOTICE

A normal but significant condition occurred

LOG_INFO

Informational message

LOG_DEBUG

Debugging information

Each priority level also has a shortcut method that logs with it's named priority. As an example, the two following statements would produce the same result:

Syslog.log(Syslog::LOG_ALERT, "Out of memory")
Syslog.alert("Out of memory")

Format strings are as for printf/sprintf, except that in addition %m is replaced with the error message string that would be returned by strerror(errno).

static VALUE mSyslog_log(int argc, VALUE *argv, VALUE self)
{
    VALUE pri;

    if (argc < 2) {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 2+)", argc);
    }

    argc--;
    pri = *argv++;

    if (!FIXNUM_P(pri)) {
        rb_raise(rb_eTypeError, "type mismatch: %"PRIsVALUE" given", rb_obj_class(pri));
    }

    syslog_write(FIX2INT(pri), argc, argv);

    return self;
}
mask() click to toggle source

Returns the log priority mask in effect. The mask is not reset by opening or closing syslog.

static VALUE mSyslog_get_mask(VALUE self)
{
    return syslog_opened ? INT2NUM(syslog_mask) : Qnil;
}
mask=(priority_mask) click to toggle source

Sets the log priority mask. A method LOG_UPTO is defined to make it easier to set mask values. Example:

Syslog.mask = Syslog::LOG_UPTO(Syslog::LOG_ERR)

Alternatively, specific priorities can be selected and added together using binary OR. Example:

Syslog.mask = Syslog::LOG_MASK(Syslog::LOG_ERR) | Syslog::LOG_MASK(Syslog::LOG_CRIT)

The priority mask persists through calls to open() and close().

static VALUE mSyslog_set_mask(VALUE self, VALUE mask)
{
    rb_secure(4);
    if (!syslog_opened) {
        rb_raise(rb_eRuntimeError, "must open syslog before setting log mask");
    }

    setlogmask(syslog_mask = NUM2INT(mask));

    return mask;
}
open(ident, options, facility) → syslog click to toggle source

Open the syslog facility. Raises a runtime exception if it is already open.

Can be called with or without a code block. If called with a block, the Syslog object created is passed to the block.

If the syslog is already open, raises a RuntimeError.

ident is a String which identifies the calling program.

options is the logical OR of any of the following:

LOG_CONS

If there is an error while sending to the system logger, write directly to the console instead.

LOG_NDELAY

Open the connection now, rather than waiting for the first message to be written.

LOG_NOWAIT

Don't wait for any child processes created while logging messages. (Has no effect on Linux.)

LOG_ODELAY

Opposite of LOG_NDELAY; wait until a message is sent before opening the connection. (This is the default.)

LOG_PERROR

Print the message to stderr as well as sending it to syslog. (Not in POSIX.1-2001.)

LOG_PID

Include the current process ID with each message.

facility describes the type of program opening the syslog, and is the logical OR of any of the following which are defined for the host OS:

LOG_AUTH

Security or authorization. Deprecated, use LOG_AUTHPRIV instead.

LOG_AUTHPRIV

Security or authorization messages which should be kept private.

LOG_CONSOLE

System console message.

LOG_CRON

System task scheduler (cron or at).

LOG_DAEMON

A system daemon which has no facility value of its own.

LOG_FTP

An FTP server.

LOG_KERN

A kernel message (not sendable by user processes, so not of much use to Ruby, but listed here for completeness).

LOG_LPR

Line printer subsystem.

LOG_MAIL

Mail delivery or transport subsystem.

LOG_NEWS

Usenet news system.

LOG_NTP

Network Time Protocol server.

LOG_SECURITY

General security message.

LOG_SYSLOG

Messages generated internally by syslog.

LOG_USER

Generic user-level message.

LOG_UUCP

UUCP subsystem.

LOG_LOCAL0 to LOG_LOCAL7

Locally-defined facilities.

Example:

Syslog.open("webrick", Syslog::LOG_PID,
            Syslog::LOG_DAEMON | Syslog::LOG_LOCAL3)
static VALUE mSyslog_open(int argc, VALUE *argv, VALUE self)
{
    VALUE ident, opt, fac;

    if (syslog_opened) {
        rb_raise(rb_eRuntimeError, "syslog already open");
    }

    rb_scan_args(argc, argv, "03", &ident, &opt, &fac);

    if (NIL_P(ident)) {
        ident = rb_gv_get("$0");
    }
    SafeStringValue(ident);
    syslog_ident = strdup(RSTRING_PTR(ident));

    if (NIL_P(opt)) {
        syslog_options = LOG_PID | LOG_CONS;
    } else {
        syslog_options = NUM2INT(opt);
    }

    if (NIL_P(fac)) {
        syslog_facility = LOG_USER;
    } else {
        syslog_facility = NUM2INT(fac);
    }

    openlog(syslog_ident, syslog_options, syslog_facility);

    syslog_opened = 1;

    setlogmask(syslog_mask = setlogmask(0));

    /* be like File.new.open {...} */
    if (rb_block_given_p()) {
        rb_ensure(rb_yield, self, mSyslog_close, self);
    }

    return self;
}
reopen(ident, options, facility) → syslog click to toggle source

Closes and then reopens the syslog.

Arguments are the same as for open().

static VALUE mSyslog_reopen(int argc, VALUE *argv, VALUE self)
{
    mSyslog_close(self);

    return mSyslog_open(argc, argv, self);
}
opened? click to toggle source

Returns true if the syslog is open.

static VALUE mSyslog_isopen(VALUE self)
{
    return syslog_opened ? Qtrue : Qfalse;
}
options() click to toggle source

Returns the options bitmask used in the last call to open()

static VALUE mSyslog_options(VALUE self)
{
    return syslog_opened ? INT2NUM(syslog_options) : Qnil;
}
reopen(ident, options, facility) → syslog click to toggle source

Closes and then reopens the syslog.

Arguments are the same as for open().

static VALUE mSyslog_reopen(int argc, VALUE *argv, VALUE self)
{
    mSyslog_close(self);

    return mSyslog_open(argc, argv, self);
}


module Syslog::Constants - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Syslog::Constants

In Files

  • ext/syslog/syslog.c

Included Modules

  • Syslog::Option
  • Syslog::Facility
  • Syslog::Level

Public Class Methods

included(p1) click to toggle source
static VALUE mSyslogMacros_included(VALUE mod, VALUE target)
{
    rb_extend_object(target, mSyslogMacros);
    return mod;
}


module Syslog::Facility - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Syslog::Facility

In Files

  • ext/syslog/syslog.c


module Syslog::Level - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Syslog::Level

In Files

  • ext/syslog/syslog.c


class Syslog::Logger - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Syslog::Logger

Syslog::Logger is a Logger work-alike that logs via syslog instead of to a file. You can use Syslog::Logger to aggregate logs between multiple machines.

By default, Syslog::Logger uses the program name 'ruby', but this can be changed via the first argument to ::new.

NOTE! You can only set the Syslog::Logger program name when you initialize Syslog::Logger for the first time. This is a limitation of the way Syslog::Logger uses syslog (and in some ways, a limitation of the way syslog(3) works). Attempts to change Syslog::Logger's program name after the first initialization will be ignored.

Example

The following will log to syslogd on your local machine:

require 'syslog/logger'

log = Syslog::Logger.new 'my_program'
log.info 'this line will be logged via syslog(3)'

You may need to perform some syslog.conf setup first. For a BSD machine add the following lines to /etc/syslog.conf:

!my_program
*.*                                             /var/log/my_program.log

Then touch /var/log/my_program.log and signal syslogd with a HUP (killall -HUP syslogd, on FreeBSD).

If you wish to have logs automatically roll over and archive, see the newsyslog.conf(5) and newsyslog(8) man pages.

In Files

  • ext/syslog/lib/syslog/logger.rb

Parent

Object

Constants

LEVEL_MAP

Maps Logger warning types to syslog(3) warning types.

Messages from ruby applications are not considered as critical as messages from other system daemons using syslog(3), so most messages are reduced by one level. For example, a fatal message for ruby's Logger is considered an error for syslog(3).

VERSION

The version of Syslog::Logger you are using.

Attributes

formatter[RW]

Logging formatter, as a Proc that will take four arguments and return the formatted message. The arguments are:

severity

The Severity of the log message.

time

A Time instance representing when the message was logged.

progname

The progname configured, or passed to the logger method.

msg

The Object the user passed to the log message; not necessarily a String.

The block should return an Object that can be written to the logging device via write. The default formatter is used when no formatter is set.

level[RW]

Log level for Logger compatibility.

Public Class Methods

make_methods(meth) click to toggle source

Builds a methods for level meth.

# File ext/syslog/lib/syslog/logger.rb, line 98
  def self.make_methods meth
    level = ::Logger.const_get(meth.upcase)
    eval "      def #{meth}(message = nil, &block)
        add(#{level}, message, &block)
      end

      def #{meth}?
        @level <= #{level}
      end
", nil, __FILE__, __LINE__ + 1
  end
new(program_name = 'ruby') click to toggle source

Fills in variables for Logger compatibility. If this is the first instance of Syslog::Logger, program_name may be set to change the logged program name.

Due to the way syslog works, only one program name may be chosen.

# File ext/syslog/lib/syslog/logger.rb, line 177
def initialize program_name = 'ruby'
  @level = ::Logger::DEBUG
  @formatter = Formatter.new

  @@syslog ||= Syslog.open(program_name)
end
syslog() click to toggle source

Returns the internal Syslog object that is initialized when the first instance is created.

# File ext/syslog/lib/syslog/logger.rb, line 84
def self.syslog
  @@syslog
end
syslog=(syslog) click to toggle source

Specifies the internal Syslog object to be used.

# File ext/syslog/lib/syslog/logger.rb, line 91
def self.syslog= syslog
  @@syslog = syslog
end

Public Instance Methods

add(severity, message = nil, progname = nil, &block) click to toggle source

Almost duplicates #add. progname is ignored.

# File ext/syslog/lib/syslog/logger.rb, line 187
def add severity, message = nil, progname = nil, &block
  severity ||= ::Logger::UNKNOWN
  @level <= severity and
    @@syslog.log LEVEL_MAP[severity], '%s', formatter.call(severity, Time.now, progname, (message || block.call))
  true
end
debug() click to toggle source

Logs a message at the debug (syslog debug) log level, or logs the message returned from the block.

# File ext/syslog/lib/syslog/logger.rb, line 147
error() click to toggle source

Logs a message at the error (syslog warning) log level, or logs the message returned from the block.

# File ext/syslog/lib/syslog/logger.rb, line 129
fatal() click to toggle source

Logs a message at the fatal (syslog err) log level, or logs the message returned from the block.

# File ext/syslog/lib/syslog/logger.rb, line 123
info() click to toggle source

Logs a message at the info (syslog info) log level, or logs the message returned from the block.

# File ext/syslog/lib/syslog/logger.rb, line 141
unknown() click to toggle source

Logs a message at the unknown (syslog alert) log level, or logs the message returned from the block.

# File ext/syslog/lib/syslog/logger.rb, line 117
warn() click to toggle source

Logs a message at the warn (syslog notice) log level, or logs the message returned from the block.

# File ext/syslog/lib/syslog/logger.rb, line 135


class Syslog::Logger::Formatter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Syslog::Logger::Formatter

Default formatter for log messages.

In Files

  • ext/syslog/lib/syslog/logger.rb

Parent

Object

Public Instance Methods

call(severity, time, progname, msg) click to toggle source
# File ext/syslog/lib/syslog/logger.rb, line 42
def call severity, time, progname, msg
  clean msg
end


module Syslog::Macros - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Syslog::Macros

In Files

  • ext/syslog/syslog.c

Public Class Methods

included(p1) click to toggle source
static VALUE mSyslogMacros_included(VALUE mod, VALUE target)
{
    rb_extend_object(target, mSyslogMacros);
    return mod;
}

Public Instance Methods

LOG_MASK(priority_level) → priority_mask click to toggle source

Generates a mask bit for a priority level. See mask=

static VALUE mSyslogMacros_LOG_MASK(VALUE mod, VALUE pri)
{
    return INT2FIX(LOG_MASK(NUM2INT(pri)));
}
LOG_UPTO(priority_level) → priority_mask click to toggle source

Generates a mask value for priority levels at or below the level specified. See mask=

static VALUE mSyslogMacros_LOG_UPTO(VALUE mod, VALUE pri)
{
    return INT2FIX(LOG_UPTO(NUM2INT(pri)));
}


module Syslog::Option - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Syslog::Option

In Files

  • ext/syslog/syslog.c


class TCPServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class TCPServer

TCPServer represents a TCP/IP server socket.

A simple TCP server may look like:

require 'socket'

server = TCPServer.new 2000 # Server bind to port 2000
loop do
  client = server.accept    # Wait for a client to connect
  client.puts "Hello !"
  client.puts "Time is #{Time.now}"
  client.close
end

A more usable server (serving multiple clients):

require 'socket'

server = TCPServer.new 2000
loop do
  Thread.start(server.accept) do |client|
    client.puts "Hello !"
    client.puts "Time is #{Time.now}"
    client.close
  end
end

In Files

  • ext/socket/tcpserver.c

Parent

TCPSocket

Public Class Methods

new([hostname,] port) → tcpserver click to toggle source

Creates a new server socket bound to port.

If hostname is given, the socket is bound to it.

serv = TCPServer.new("127.0.0.1", 28561)
s = serv.accept
s.puts Time.now
s.close
static VALUE
tcp_svr_init(int argc, VALUE *argv, VALUE sock)
{
    VALUE hostname, port;

    rb_scan_args(argc, argv, "011", &hostname, &port);
    return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER);
}

Public Instance Methods

accept → tcpsocket click to toggle source

TCPServer.open(“127.0.0.1”, 14641) {|serv|

s = serv.accept
s.puts Time.now
s.close

}

static VALUE
tcp_accept(VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_storage from;
    socklen_t fromlen;

    GetOpenFile(sock, fptr);
    fromlen = (socklen_t)sizeof(from);
    return rsock_s_accept(rb_cTCPSocket, fptr->fd,
                          (struct sockaddr*)&from, &fromlen);
}
accept_nonblock → tcpsocket click to toggle source

Accepts an incoming connection using accept(2) after O_NONBLOCK is set for the underlying file descriptor. It returns an accepted TCPSocket for the incoming connection.

Example

require 'socket'
serv = TCPServer.new(2202)
begin # emulate blocking accept
  sock = serv.accept_nonblock
rescue IO::WaitReadable, Errno::EINTR
  IO.select([serv])
  retry
end
# sock is an accepted socket.

Refer to Socket#accept for the exceptions that may be thrown if the call to #accept_nonblock fails.

#accept_nonblock may raise any error corresponding to accept(2) failure, including Errno::EWOULDBLOCK.

If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED, Errno::EPROTO, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.

See

  • #accept

  • Socket#accept

static VALUE
tcp_accept_nonblock(VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_storage from;
    socklen_t fromlen;

    GetOpenFile(sock, fptr);
    fromlen = (socklen_t)sizeof(from);
    return rsock_s_accept_nonblock(rb_cTCPSocket, fptr,
                                   (struct sockaddr *)&from, &fromlen);
}
listen( int ) → 0 click to toggle source

Listens for connections, using the specified int as the backlog. A call to listen only applies if the socket is of type SOCK_STREAM or SOCK_SEQPACKET.

Parameter

  • backlog - the maximum length of the queue for pending connections.

Example 1

require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
socket.bind( sockaddr )
socket.listen( 5 )

Example 2 (listening on an arbitrary port, unix-based systems only):

require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
socket.listen( 1 )

Unix-based Exceptions

On unix based systems the above will work because a new sockaddr struct is created on the address ADDR_ANY, for an arbitrary port number as handed off by the kernel. It will not work on Windows, because Windows requires that the socket is bound by calling bind before it can listen.

If the backlog amount exceeds the implementation-dependent maximum queue length, the implementation's maximum queue length will be used.

On unix-based based systems the following system exceptions may be raised if the call to listen fails:

  • Errno::EBADF - the socket argument is not a valid file descriptor

  • Errno::EDESTADDRREQ - the socket is not bound to a local address, and the protocol does not support listening on an unbound socket

  • Errno::EINVAL - the socket is already connected

  • Errno::ENOTSOCK - the socket argument does not refer to a socket

  • Errno::EOPNOTSUPP - the socket protocol does not support listen

  • Errno::EACCES - the calling process does not have appropriate privileges

  • Errno::EINVAL - the socket has been shut down

  • Errno::ENOBUFS - insufficient resources are available in the system to complete the call

Windows Exceptions

On Windows systems the following system exceptions may be raised if the call to listen fails:

  • Errno::ENETDOWN - the network is down

  • Errno::EADDRINUSE - the socket's local address is already in use. This usually occurs during the execution of bind but could be delayed if the call to bind was to a partially wildcard address (involving ADDR_ANY) and if a specific address needs to be committed at the time of the call to listen

  • Errno::EINPROGRESS - a Windows Sockets 1.1 call is in progress or the service provider is still processing a callback function

  • Errno::EINVAL - the socket has not been bound with a call to bind.

  • Errno::EISCONN - the socket is already connected

  • Errno::EMFILE - no more socket descriptors are available

  • Errno::ENOBUFS - no buffer space is available

  • Errno::ENOTSOC - socket is not a socket

  • Errno::EOPNOTSUPP - the referenced socket is not a type that supports the listen method

See

  • listen manual pages on unix-based systems

  • listen function in Microsoft's Winsock functions reference

VALUE
rsock_sock_listen(VALUE sock, VALUE log)
{
    rb_io_t *fptr;
    int backlog;

    rb_secure(4);
    backlog = NUM2INT(log);
    GetOpenFile(sock, fptr);
    if (listen(fptr->fd, backlog) < 0)
    rb_sys_fail("listen(2)");

    return INT2FIX(0);
}
sysaccept → file_descriptor click to toggle source

Returns a file descriptor of a accepted connection.

TCPServer.open("127.0.0.1", 28561) {|serv|
  fd = serv.sysaccept
  s = IO.for_fd(fd)
  s.puts Time.now
  s.close
}

static VALUE
tcp_sysaccept(VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_storage from;
    socklen_t fromlen;

    GetOpenFile(sock, fptr);
    fromlen = (socklen_t)sizeof(from);
    return rsock_s_accept(0, fptr->fd, (struct sockaddr*)&from, &fromlen);
}


class TCPSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class TCPSocket

TCPSocket represents a TCP/IP client socket.

A simple client may look like:

require 'socket'

s = TCPSocket.new 'localhost', 2000

while line = s.gets # Read lines from socket
  puts line         # and print them
end

s.close             # close socket when done

In Files

  • lib/resolv-replace.rb
  • ext/socket/tcpsocket.c

Parent

IPSocket

Public Class Methods

gethostbyname(hostname) → [official_hostname, alias_hostnames, address_family, *address_list] click to toggle source

Lookups host information by hostname.

TCPSocket.gethostbyname("localhost")
#=> ["localhost", ["hal"], 2, "127.0.0.1"]

static VALUE
tcp_s_gethostbyname(VALUE obj, VALUE host)
{
    rb_secure(3);
    return rsock_make_hostent(host, rsock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME),
                        tcp_sockaddr);
}
new(host, serv, *rest) click to toggle source
# File lib/resolv-replace.rb, line 21
def initialize(host, serv, *rest)
  rest[0] = IPSocket.getaddress(rest[0]) if rest[0]
  original_resolv_initialize(IPSocket.getaddress(host), serv, *rest)
end
new(remote_host, remote_port, local_host=nil, local_port=nil) click to toggle source

Opens a TCP connection to remote_host on remote_port. If local_host and local_port are specified, then those parameters are used on the local end to establish the connection.

static VALUE
tcp_init(int argc, VALUE *argv, VALUE sock)
{
    VALUE remote_host, remote_serv;
    VALUE local_host, local_serv;

    rb_scan_args(argc, argv, "22", &remote_host, &remote_serv,
                        &local_host, &local_serv);

    return rsock_init_inetsock(sock, remote_host, remote_serv,
                               local_host, local_serv, INET_CLIENT);
}


module TSort - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module TSort

TSort implements topological sorting using Tarjan's algorithm for strongly connected components.

TSort is designed to be able to be used with any object which can be interpreted as a directed graph.

TSort requires two methods to interpret an object as a graph, #tsort_each_node and tsort_each_child.

  • #tsort_each_node is used to iterate for all nodes over a graph.

  • #tsort_each_child is used to iterate for child nodes of a given node.

The equality of nodes are defined by eql? and hash since TSort uses Hash internally.

A Simple Example

The following example demonstrates how to mix the TSort module into an existing class (in this case, Hash). Here, we're treating each key in the hash as a node in the graph, and so we simply alias the required tsort_each_node method to Hash's each_key method. For each key in the hash, the associated value is an array of the node's child nodes. This choice in turn leads to our implementation of the required tsort_each_child method, which fetches the array of child nodes and then iterates over that array using the user-supplied block.

require 'tsort'

class Hash
  include TSort
  alias tsort_each_node each_key
  def tsort_each_child(node, &block)
    fetch(node).each(&block)
  end
end

{1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
#=> [3, 2, 1, 4]

{1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
#=> [[4], [2, 3], [1]]

A More Realistic Example

A very simple `make' like tool can be implemented as follows:

require 'tsort'

class Make
  def initialize
    @dep = {}
    @dep.default = []
  end

  def rule(outputs, inputs=[], &block)
    triple = [outputs, inputs, block]
    outputs.each {|f| @dep[f] = [triple]}
    @dep[triple] = inputs
  end

  def build(target)
    each_strongly_connected_component_from(target) {|ns|
      if ns.length != 1
        fs = ns.delete_if {|n| Array === n}
        raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
      end
      n = ns.first
      if Array === n
        outputs, inputs, block = n
        inputs_time = inputs.map {|f| File.mtime f}.max
        begin
          outputs_time = outputs.map {|f| File.mtime f}.min
        rescue Errno::ENOENT
          outputs_time = nil
        end
        if outputs_time == nil ||
           inputs_time != nil && outputs_time <= inputs_time
          sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
          block.call
        end
      end
    }
  end

  def tsort_each_child(node, &block)
    @dep[node].each(&block)
  end
  include TSort
end

def command(arg)
  print arg, "\n"
  system arg
end

m = Make.new
m.rule(%w[t1]) { command 'date > t1' }
m.rule(%w[t2]) { command 'date > t2' }
m.rule(%w[t3]) { command 'date > t3' }
m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
m.build('t5')

Bugs

  • 'tsort.rb' is wrong name because this library uses Tarjan's algorithm for strongly connected components. Although 'strongly_connected_components.rb' is correct but too long.

References

    1. Tarjan, “Depth First Search and Linear Graph Algorithms”,

SIAM Journal on Computing, Vol. 1, No. 2, pp. 146-160, June 1972.

In Files

  • lib/tsort.rb

Public Instance Methods

each_strongly_connected_component() { |nodes| ... } click to toggle source

The iterator version of the strongly_connected_components method. obj.each_strongly_connected_component is similar to obj.strongly_connected_components.each, but modification of obj during the iteration may lead to unexpected results.

each_strongly_connected_component returns nil.

# File lib/tsort.rb, line 177
def each_strongly_connected_component # :yields: nodes
  id_map = {}
  stack = []
  tsort_each_node {|node|
    unless id_map.include? node
      each_strongly_connected_component_from(node, id_map, stack) {|c|
        yield c
      }
    end
  }
  nil
end
each_strongly_connected_component_from(node, id_map={}, stack=[]) { |nodes| ... } click to toggle source

Iterates over strongly connected component in the subgraph reachable from node.

Return value is unspecified.

each_strongly_connected_component_from doesn't call tsort_each_node.

# File lib/tsort.rb, line 198
def each_strongly_connected_component_from(node, id_map={}, stack=[]) # :yields: nodes
  minimum_id = node_id = id_map[node] = id_map.size
  stack_length = stack.length
  stack << node

  tsort_each_child(node) {|child|
    if id_map.include? child
      child_id = id_map[child]
      minimum_id = child_id if child_id && child_id < minimum_id
    else
      sub_minimum_id =
        each_strongly_connected_component_from(child, id_map, stack) {|c|
          yield c
        }
      minimum_id = sub_minimum_id if sub_minimum_id < minimum_id
    end
  }

  if node_id == minimum_id
    component = stack.slice!(stack_length .. -1)
    component.each {|n| id_map[n] = nil}
    yield component
  end

  minimum_id
end
strongly_connected_components() click to toggle source

Returns strongly connected components as an array of arrays of nodes. The array is sorted from children to parents. Each elements of the array represents a strongly connected component.

# File lib/tsort.rb, line 162
def strongly_connected_components
  result = []
  each_strongly_connected_component {|component| result << component}
  result
end
tsort() click to toggle source

Returns a topologically sorted array of nodes. The array is sorted from children to parents, i.e. the first element has no child and the last node has no parent.

If there is a cycle, TSort::Cyclic is raised.

# File lib/tsort.rb, line 133
def tsort
  result = []
  tsort_each {|element| result << element}
  result
end
tsort_each() { |node| ... } click to toggle source

The iterator version of the tsort method. obj.tsort_each is similar to obj.tsort.each, but modification of obj during the iteration may lead to unexpected results.

tsort_each returns nil. If there is a cycle, TSort::Cyclic is raised.

# File lib/tsort.rb, line 147
def tsort_each # :yields: node
  each_strongly_connected_component {|component|
    if component.size == 1
      yield component.first
    else
      raise Cyclic.new("topological sort failed: #{component.inspect}")
    end
  }
end
tsort_each_child(node) { |child| ... } click to toggle source

Should be implemented by a extended class.

tsort_each_child is used to iterate for child nodes of node.

# File lib/tsort.rb, line 239
def tsort_each_child(node) # :yields: child
  raise NotImplementedError.new
end
tsort_each_node() { |node| ... } click to toggle source

Should be implemented by a extended class.

tsort_each_node is used to iterate for all nodes over a graph.

# File lib/tsort.rb, line 230
def tsort_each_node # :yields: node
  raise NotImplementedError.new
end


class TSort::Cyclic - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class TSort::Cyclic

In Files

  • lib/tsort.rb

Parent

StandardError


class TempIO - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class TempIO

A StringIO duck-typed class that uses Tempfile instead of String as the backing store.

This is available when rubygems/test_utilities is required.

In Files

  • lib/rubygems/test_utilities.rb

Parent

Tempfile

Public Class Methods

new(string = '') click to toggle source
# File lib/rubygems/test_utilities.rb, line 171
def initialize(string = '')
  super "TempIO"
  binmode
  write string
  rewind
end

Public Instance Methods

string() click to toggle source
# File lib/rubygems/test_utilities.rb, line 178
def string
  flush
  Gem.read_binary path
end


class Tempfile - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Tempfile

A utility class for managing temporary files. When you create a Tempfile object, it will create a temporary file with a unique filename. A Tempfile objects behaves just like a File object, and you can perform all the usual file operations on it: reading data, writing data, changing its permissions, etc. So although this class does not explicitly document all instance methods supported by File, you can in fact call any File instance method on a Tempfile object.

Synopsis

require 'tempfile'

file = Tempfile.new('foo')
file.path      # => A unique filename in the OS's temp directory,
               #    e.g.: "/tmp/foo.24722.0"
               #    This filename contains 'foo' in its basename.
file.write("hello world")
file.rewind
file.read      # => "hello world"
file.close
file.unlink    # deletes the temp file

Good practices

Explicit close

When a Tempfile object is garbage collected, or when the Ruby interpreter exits, its associated temporary file is automatically deleted. This means that's it's unnecessary to explicitly delete a Tempfile after use, though it's good practice to do so: not explicitly deleting unused Tempfiles can potentially leave behind large amounts of tempfiles on the filesystem until they're garbage collected. The existence of these temp files can make it harder to determine a new Tempfile filename.

Therefore, one should always call unlink or close in an ensure block, like this:

file = Tempfile.new('foo')
begin
   ...do something with file...
ensure
   file.close
   file.unlink   # deletes the temp file
end

Unlink after creation

On POSIX systems, it's possible to unlink a file right after creating it, and before closing it. This removes the filesystem entry without closing the file handle, so it ensures that only the processes that already had the file handle open can access the file's contents. It's strongly recommended that you do this if you do not want any other processes to be able to read from or write to the Tempfile, and you do not need to know the Tempfile's filename either.

For example, a practical use case for unlink-after-creation would be this: you need a large byte buffer that's too large to comfortably fit in RAM, e.g. when you're writing a web server and you want to buffer the client's file upload data.

Please refer to unlink for more information and a code example.

Minor notes

Tempfile's filename picking method is both thread-safe and inter-process-safe: it guarantees that no other threads or processes will pick the same filename.

Tempfile itself however may not be entirely thread-safe. If you access the same Tempfile object from multiple threads then you should protect it with a mutex.

In Files

  • lib/tempfile.rb

Parent

DelegateClass(File)

Public Class Methods

new(basename, [tmpdir = Dir.tmpdir], [options]) click to toggle source

Creates a temporary file with permissions 0600 (= only readable and writable by the owner) and opens it with mode “w+”.

The basename parameter is used to determine the name of the temporary file. You can either pass a String or an Array with 2 String elements. In the former form, the temporary file's base name will begin with the given string. In the latter form, the temporary file's base name will begin with the array's first element, and end with the second element. For example:

file = Tempfile.new('hello')
file.path  # => something like: "/tmp/hello2843-8392-92849382--0"

# Use the Array form to enforce an extension in the filename:
file = Tempfile.new(['hello', '.jpg'])
file.path  # => something like: "/tmp/hello2843-8392-92849382--0.jpg"

The temporary file will be placed in the directory as specified by the tmpdir parameter. By default, this is Dir.tmpdir. When $SAFE > 0 and the given tmpdir is tainted, it uses '/tmp' as the temporary directory. Please note that ENV values are tainted by default, and Dir.tmpdir's return value might come from environment variables (e.g. $TMPDIR).

file = Tempfile.new('hello', '/home/aisaka')
file.path  # => something like: "/home/aisaka/hello2843-8392-92849382--0"

You can also pass an options hash. Under the hood, Tempfile creates the temporary file using File.open. These options will be passed to File.open. This is mostly useful for specifying encoding options, e.g.:

Tempfile.new('hello', '/home/aisaka', :encoding => 'ascii-8bit')

# You can also omit the 'tmpdir' parameter:
Tempfile.new('hello', :encoding => 'ascii-8bit')

Exceptions

If ::new cannot find a unique filename within a limited number of tries, then it will raise an exception.

# File lib/tempfile.rb, line 128
def initialize(basename, *rest)
  if block_given?
    warn "Tempfile.new doesn't call the given block."
  end
  @data = []
  @clean_proc = Remover.new(@data)
  ObjectSpace.define_finalizer(self, @clean_proc)

  create(basename, *rest) do |tmpname, n, opts|
    mode = File::RDWR|File::CREAT|File::EXCL
    perm = 0600
    if opts
      mode |= opts.delete(:mode) || 0
      opts[:perm] = perm
      perm = nil
    else
      opts = perm
    end
    @data[1] = @tmpfile = File.open(tmpname, mode, opts)
    @data[0] = @tmpname = tmpname
    @mode = mode & ~(File::CREAT|File::EXCL)
    perm or opts.freeze
    @opts = opts
  end

  super(@tmpfile)
end
open(*args) { |tempfile| ... } click to toggle source

Creates a new Tempfile.

If no block is given, this is a synonym for ::new.

If a block is given, then a Tempfile object will be constructed, and the block is run with said object as argument. The Tempfile object will be automatically closed after the block terminates. The call returns the value of the block.

In any case, all arguments (+*args+) will be passed to ::new.

Tempfile.open('foo', '/home/temp') do |f|
   ... do something with f ...
end

# Equivalent:
f = Tempfile.open('foo', '/home/temp')
begin
   ... do something with f ...
ensure
   f.close
end

# File lib/tempfile.rb, line 319
def open(*args)
  tempfile = new(*args)

  if block_given?
    begin
      yield(tempfile)
    ensure
      tempfile.close
    end
  else
    tempfile
  end
end

Public Instance Methods

close(unlink_now=false) click to toggle source

Closes the file. If unlink_now is true, then the file will be unlinked (deleted) after closing. Of course, you can choose to later call unlink if you do not unlink it now.

If you don't explicitly unlink the temporary file, the removal will be delayed until the object is finalized.

# File lib/tempfile.rb, line 180
def close(unlink_now=false)
  if unlink_now
    close!
  else
    _close
  end
end
close!() click to toggle source

Closes and unlinks (deletes) the file. Has the same effect as called close(true).

# File lib/tempfile.rb, line 190
def close!
  _close
  unlink
end
delete() click to toggle source
Alias for: unlink
inspect() click to toggle source
# File lib/tempfile.rb, line 264
def inspect
  "#<#{self.class}:#{path}>"
end
length() click to toggle source
Alias for: size
open() click to toggle source

Opens or reopens the file with mode “r+”.

# File lib/tempfile.rb, line 157
def open
  @tmpfile.close if @tmpfile
  @tmpfile = File.open(@tmpname, @mode, @opts)
  @data[1] = @tmpfile
  __setobj__(@tmpfile)
end
path() click to toggle source

Returns the full path name of the temporary file. This will be nil if unlink has been called.

# File lib/tempfile.rb, line 246
def path
  @tmpname
end
size() click to toggle source

Returns the size of the temporary file. As a side effect, the IO buffer is flushed before determining the size.

# File lib/tempfile.rb, line 252
def size
  if @tmpfile
    @tmpfile.flush
    @tmpfile.stat.size
  elsif @tmpname
    File.size(@tmpname)
  else
    0
  end
end
Also aliased as: length
unlink() click to toggle source

Unlinks (deletes) the file from the filesystem. One should always unlink the file after using it, as is explained in the “Explicit close” good practice section in the Tempfile overview:

file = Tempfile.new('foo')
begin
   ...do something with file...
ensure
   file.close
   file.unlink   # deletes the temp file
end

Unlink-before-close

On POSIX systems it's possible to unlink a file before closing it. This practice is explained in detail in the Tempfile overview (section “Unlink after creation”); please refer there for more information.

However, unlink-before-close may not be supported on non-POSIX operating systems. Microsoft Windows is the most notable case: unlinking a non-closed file will result in an error, which this method will silently ignore. If you want to practice unlink-before-close whenever possible, then you should write code like this:

file = Tempfile.new('foo')
file.unlink   # On Windows this silently fails.
begin
   ... do something with file ...
ensure
   file.close!   # Closes the file handle. If the file wasn't unlinked
                 # because #unlink failed, then this method will attempt
                 # to do so again.
end
# File lib/tempfile.rb, line 228
def unlink
  return unless @tmpname
  begin
    File.unlink(@tmpname)
  rescue Errno::ENOENT
  rescue Errno::EACCES
    # may not be able to unlink on Windows; just ignore
    return
  end
  # remove tmpname from remover
  @data[0] = @data[1] = nil
  @tmpname = nil
  ObjectSpace.undefine_finalizer(self)
end
Also aliased as: delete


class Tempfile::Remover - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Tempfile::Remover

In Files

  • lib/tempfile.rb

Parent

Object


module Test - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Test

In Files

  • lib/minitest/unit.rb
  • lib/rake/ruby182_test_unit_fix.rb
  • lib/test/unit/assertions.rb
  • lib/test/unit/parallel.rb
  • lib/test/unit/testcase.rb
  • lib/test/unit.rb


module Test::Unit - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Test::Unit

In Files

  • lib/minitest/unit.rb
  • lib/rake/ruby182_test_unit_fix.rb
  • lib/test/unit/assertions.rb
  • lib/test/unit/parallel.rb
  • lib/test/unit/testcase.rb
  • lib/test/unit.rb

Constants

TEST_UNIT_IMPLEMENTATION


module Test::Unit::Assertions - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Test::Unit::Assertions

In Files

  • lib/test/unit/assertions.rb

Included Modules

  • MiniTest::Assertions

Public Instance Methods

assert( test, failure_message = UNASSIGNED ) click to toggle source

Tests if test is true.

msg may be a String or a Proc. If msg is a String, it will be used as the failure message. Otherwise, the result of calling msg will be used as the message if the assertion fails.

If no msg is given, a default message will be used.

assert(false, "This was expected to be true")
# File lib/test/unit/assertions.rb, line 29
def assert(test, msg = UNASSIGNED)
  case msg
  when UNASSIGNED
    msg = nil
  when String, Proc
  else
    bt = caller.reject { |s| s.rindex(MINI_DIR, 0) }
    raise ArgumentError, "assertion message must be String or Proc, but #{msg.class} was given.", bt
  end
  super
end
assert_block( failure_message = nil ) click to toggle source

Tests the result of the given block. If the block does not return true, the assertion will fail. The optional failure_message argument is the same as in #assert.

assert_block do
  [1, 2, 3].any? { |num| num < 1 }
end

# File lib/test/unit/assertions.rb, line 51
def assert_block(*msgs)
  assert yield, *msgs
end
assert_equal( expected, actual, failure_message = nil ) click to toggle source

Tests if expected is equal to actual.

An optional failure message may be provided as the final argument.

# File lib/test/unit/assertions.rb, line 144
def assert_equal(exp, act, msg = nil)
  msg = message(msg) {
    exp_str = mu_pp(exp)
    act_str = mu_pp(act)
    exp_comment = ''
    act_comment = ''
    if exp_str == act_str
      if (exp.is_a?(String) && act.is_a?(String)) ||
         (exp.is_a?(Regexp) && act.is_a?(Regexp))
        exp_comment = " (#{exp.encoding})"
        act_comment = " (#{act.encoding})"
      elsif exp.is_a?(Float) && act.is_a?(Float)
        exp_str = "%\#.#{Float::DIG+2}g" % exp
        act_str = "%\#.#{Float::DIG+2}g" % act
      elsif exp.is_a?(Time) && act.is_a?(Time)
        if exp.subsec * 1000_000_000 == exp.nsec
          exp_comment = " (#{exp.nsec}[ns])"
        else
          exp_comment = " (subsec=#{exp.subsec})"
        end
        if act.subsec * 1000_000_000 == act.nsec
          act_comment = " (#{act.nsec}[ns])"
        else
          act_comment = " (subsec=#{act.subsec})"
        end
      elsif exp.class != act.class
        # a subclass of Range, for example.
        exp_comment = " (#{exp.class})"
        act_comment = " (#{act.class})"
      end
    elsif !Encoding.compatible?(exp_str, act_str)
      if exp.is_a?(String) && act.is_a?(String)
        exp_str = exp.dump
        act_str = act.dump
        exp_comment = " (#{exp.encoding})"
        act_comment = " (#{act.encoding})"
      else
        exp_str = exp_str.dump
        act_str = act_str.dump
      end
    end
    "<#{exp_str}>#{exp_comment} expected but was\n<#{act_str}>#{act_comment}"
  }
  assert(exp == act, msg)
end
assert_no_match( regexp, string, failure_message = nil ) click to toggle source

Tests if the given Regexp does not match a given String.

An optional failure message may be provided as the final argument.

# File lib/test/unit/assertions.rb, line 218
def assert_no_match(regexp, string, msg=nil)
  assert_instance_of(Regexp, regexp, "The first argument to assert_no_match should be a Regexp.")
  self._assertions -= 1
  msg = message(msg) { "<#{mu_pp(regexp)}> expected to not match\n<#{mu_pp(string)}>" }
  assert(regexp !~ string, msg)
end
assert_not_equal( expected, actual, failure_message = nil ) click to toggle source

Tests if expected is not equal to actual.

An optional failure message may be provided as the final argument.

# File lib/test/unit/assertions.rb, line 207
def assert_not_equal(exp, act, msg=nil)
  msg = message(msg) { "<#{mu_pp(exp)}> expected to be != to\n<#{mu_pp(act)}>" }
  assert(exp != act, msg)
end
assert_not_nil( expression, failure_message = nil ) click to toggle source

Tests if expression is not nil.

An optional failure message may be provided as the final argument.

# File lib/test/unit/assertions.rb, line 196
def assert_not_nil(exp, msg=nil)
  msg = message(msg) { "<#{mu_pp(exp)}> expected to not be nil" }
  assert(!exp.nil?, msg)
end
assert_not_same( expected, actual, failure_message = nil ) click to toggle source

Tests if expected is not the same object as actual. This test uses Object#equal? to test equality.

An optional failure message may be provided as the final argument.

assert_not_same("x", "x") #Succeeds
# File lib/test/unit/assertions.rb, line 234
      def assert_not_same(expected, actual, message="")
        msg = message(msg) { build_message(message, "<?>
with id <?> expected to not be equal\\? to
<?>
with id <?>.
", expected, expected.__id__, actual, actual.__id__) }
        assert(!actual.equal?(expected), msg)
      end
assert_not_send( +send_array+, failure_message = nil ) click to toggle source

Passes if the method send doesn't return a true value.

send_array is composed of:

  • A receiver

  • A method

  • Arguments to the method

Example:

assert_not_send([[1, 2], :member?, 1]) # -> fail
assert_not_send([[1, 2], :member?, 4]) # -> pass
# File lib/test/unit/assertions.rb, line 303
def assert_not_send send_ary, m = nil
  recv, msg, *args = send_ary
  m = message(m) {
    if args.empty?
      argsstr = ""
    else
      (argsstr = mu_pp(args)).sub!(/\A\[(.*)\]\z/, '(\1)')
    end
    "Expected #{mu_pp(recv)}.#{msg}#{argsstr} to return false"
  }
  assert !recv.__send__(msg, *args), m
end
assert_nothing_raised( *args, &block ) click to toggle source

If any exceptions are given as arguments, the assertion will fail if one of those exceptions are raised. Otherwise, the test fails if any exceptions are raised.

The final argument may be a failure message.

assert_nothing_raised RuntimeError do
  raise Exception #Assertion passes, Exception is not a RuntimeError
end

assert_nothing_raised do
  raise Exception #Assertion fails
end
# File lib/test/unit/assertions.rb, line 88
def assert_nothing_raised(*args)
  self._assertions += 1
  if Module === args.last
    msg = nil
  else
    msg = args.pop
  end
  begin
    line = __LINE__; yield
  rescue MiniTest::Skip
    raise
  rescue Exception => e
    bt = e.backtrace
    as = e.instance_of?(MiniTest::Assertion)
    if as
      ans = /\A#{Regexp.quote(__FILE__)}:#{line}:in /
      bt.reject! {|ln| ans =~ ln}
    end
    if ((args.empty? && !as) ||
        args.any? {|a| a.instance_of?(Module) ? e.is_a?(a) : e.class == a })
      msg = message(msg) { "Exception raised:\n<#{mu_pp(e)}>" }
      raise MiniTest::Assertion, msg.call, bt
    else
      raise
    end
  end
  nil
end
assert_nothing_thrown( failure_message = nil, &block ) click to toggle source

Fails if the given block uses a call to Kernel#throw.

An optional failure message may be provided as the final argument.

assert_nothing_thrown "Something was thrown!" do
  throw :problem?
end
# File lib/test/unit/assertions.rb, line 127
def assert_nothing_thrown(msg=nil)
  begin
    yield
  rescue ArgumentError => error
    raise error if /\Auncaught throw (.+)\z/ !~ error.message
    msg = message(msg) { "<#{$1}> was thrown when nothing was expected" }
    flunk(msg)
  end
  assert(true, "Expected nothing to be thrown")
end
assert_raise( *args, &block ) click to toggle source

Tests if the given block raises an exception. Acceptable exception types maye be given as optional arguments. If the last argument is a String, it will be used as the error message.

assert_raise do #Fails, no Exceptions are raised
end

assert_raise NameError do
  puts x  #Raises NameError, so assertion succeeds
end
# File lib/test/unit/assertions.rb, line 68
def assert_raise(*args, &b)
  assert_raises(*args, &b)
end
assert_respond_to( object, method, failure_message = nil ) click to toggle source

Tests if the given Object responds to method.

An optional failure message may be provided as the final argument.

assert_respond_to("hello", :reverse)  #Succeeds
assert_respond_to("hello", :does_not_exist)  #Fails
# File lib/test/unit/assertions.rb, line 253
def assert_respond_to obj, (meth, priv), msg = nil
  if priv
    msg = message(msg) {
      "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}#{" privately" if priv}"
    }
    return assert obj.respond_to?(meth, priv), msg
  end
  #get rid of overcounting
  super if !caller[0].rindex(MINI_DIR, 0) || !obj.respond_to?(meth)
end
assert_send( +send_array+, failure_message = nil ) click to toggle source

Passes if the method send returns a true value.

send_array is composed of:

  • A receiver

  • A method

  • Arguments to the method

Example:

assert_send([[1, 2], :member?, 1]) # -> pass
assert_send([[1, 2], :member?, 4]) # -> fail
# File lib/test/unit/assertions.rb, line 277
def assert_send send_ary, m = nil
  recv, msg, *args = send_ary
  m = message(m) {
    if args.empty?
      argsstr = ""
    else
      (argsstr = mu_pp(args)).sub!(/\A\[(.*)\]\z/, '(\1)')
    end
    "Expected #{mu_pp(recv)}.#{msg}#{argsstr} to return true"
  }
  assert recv.__send__(msg, *args), m
end


class Test::Unit::AutoRunner - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Test::Unit::AutoRunner

In Files

  • lib/test/unit.rb

Parent

Object

Attributes

options[RW]
to_run[RW]

Public Class Methods

new(force_standalone = false, default_dir = nil, argv = ARGV) { |self| ... } click to toggle source
# File lib/test/unit.rb, line 808
def initialize(force_standalone = false, default_dir = nil, argv = ARGV)
  @force_standalone = force_standalone
  @runner = Runner.new do |files, options|
    options[:base_directory] ||= default_dir
    files << default_dir if files.empty? and default_dir
    @to_run = files
    yield self if block_given?
    files
  end
  Runner.runner = @runner
  @options = @runner.option_parser
  if @force_standalone
    @options.banner.sub!(/\[options\]/, '\& tests...')
  end
  @argv = argv
end
run(*args) click to toggle source
# File lib/test/unit.rb, line 837
def self.run(*args)
  new(*args).run
end

Public Instance Methods

process_args(*args) click to toggle source
# File lib/test/unit.rb, line 825
def process_args(*args)
  @runner.process_args(*args)
  !@to_run.empty?
end
run() click to toggle source
# File lib/test/unit.rb, line 830
def run
  if @force_standalone and not process_args(@argv)
    abort @options.banner
  end
  @runner.run(@argv) || true
end


class Test::Unit::AutoRunner::Runner - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Test::Unit::AutoRunner::Runner

In Files

  • lib/test/unit.rb

Parent

Test::Unit::Runner

Included Modules

  • Test::Unit::RequireFiles


module Test::Unit::GCStressOption - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Test::Unit::GCStressOption

In Files

  • lib/test/unit.rb

Public Instance Methods

non_options(files, options) click to toggle source
# File lib/test/unit.rb, line 217
def non_options(files, options)
  if options.delete(:gc_stress)
    MiniTest::Unit::TestCase.class_eval do
      oldrun = instance_method(:run)
      define_method(:run) do |runner|
        begin
          gc_stress, GC.stress = GC.stress, true
          oldrun.bind(self).call(runner)
        ensure
          GC.stress = gc_stress
        end
      end
    end
  end
  super
end
setup_options(parser, options) click to toggle source
# File lib/test/unit.rb, line 210
def setup_options(parser, options)
  super
  parser.on '--[no-]gc-stress', 'Set GC.stress as true' do |flag|
    options[:gc_stress] = flag
  end
end


module Test::Unit::GlobOption - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Test::Unit::GlobOption

In Files

  • lib/test/unit.rb

Public Instance Methods

non_options(files, options) click to toggle source
# File lib/test/unit.rb, line 167
def non_options(files, options)
  paths = [options.delete(:base_directory), nil].uniq
  if reject = options.delete(:reject)
    reject_pat = Regexp.union(reject.map {|r| /#{r}/ })
  end
  files.map! {|f|
    f = f.tr(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
    ((paths if /\A\.\.?(?:\z|\/)/ !~ f) || [nil]).any? do |prefix|
      if prefix
        path = f.empty? ? prefix : "#{prefix}/#{f}"
      else
        next if f.empty?
        path = f
      end
      if !(match = Dir["#{path}/**/#{@@testfile_prefix}_*.rb"]).empty?
        if reject
          match.reject! {|n|
            n[(prefix.length+1)..-1] if prefix
            reject_pat =~ n
          }
        end
        break match
      elsif !reject or reject_pat !~ f and File.exist? path
        break path
      end
    end or
      raise ArgumentError, "file not found: #{f}"
  }
  files.flatten!
  super(files, options)
end
setup_options(parser, options) click to toggle source
# File lib/test/unit.rb, line 157
def setup_options(parser, options)
  super
  parser.on '-b', '--basedir=DIR', 'Base directory of test suites.' do |dir|
    options[:base_directory] = dir
  end
  parser.on '-x', '--exclude PATTERN', 'Exclude test files on pattern.' do |pattern|
    (options[:reject] ||= []) << pattern
  end
end


module Test::Unit::LoadPathOption - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Test::Unit::LoadPathOption

In Files

  • lib/test/unit.rb

Public Instance Methods

setup_options(parser, options) click to toggle source
# File lib/test/unit.rb, line 201
def setup_options(parser, options)
  super
  parser.on '-Idirectory', 'Add library load path' do |dirs|
    dirs.split(':').each { |d| $LOAD_PATH.unshift d }
  end
end


module Test::Unit::Options - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Test::Unit::Options

In Files

  • lib/test/unit.rb

Public Class Methods

new(*, &block) click to toggle source
# File lib/test/unit.rb, line 33
def initialize(*, &block)
  @init_hook = block
  @options = nil
  super(&nil)
end

Public Instance Methods

option_parser() click to toggle source
# File lib/test/unit.rb, line 39
def option_parser
  @option_parser ||= OptionParser.new
end
process_args(args = []) click to toggle source
# File lib/test/unit.rb, line 43
def process_args(args = [])
  return @options if @options
  orig_args = args.dup
  options = {}
  opts = option_parser
  setup_options(opts, options)
  opts.parse!(args)
  orig_args -= args
  args = @init_hook.call(args, options) if @init_hook
  non_options(args, options)
  @help = orig_args.map { |s| s =~ /[\s|&<>$()]/ ? s.inspect : s }.join " "
  @options = options
  if @options[:parallel]
    @files = args
    @args = orig_args
  end
  options
end


class Test::Unit::ProxyError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Test::Unit::ProxyError

In Files

  • lib/test/unit.rb

Parent

StandardError

Attributes

backtrace[RW]
message[RW]

Public Class Methods

new(ex) click to toggle source
# File lib/test/unit.rb, line 843
def initialize(ex)
  @message = ex.message
  @backtrace = ex.backtrace
end


module Test::Unit::RequireFiles - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Test::Unit::RequireFiles

In Files

  • lib/test/unit.rb

Public Instance Methods

non_options(files, options) click to toggle source
# File lib/test/unit.rb, line 236
def non_options(files, options)
  return false if !super
  result = false
  files.each {|f|
    d = File.dirname(path = File.realpath(f))
    unless $:.include? d
      $: << d
    end
    begin
      require path unless options[:parallel]
      result = true
    rescue LoadError
      puts "#{f}: #{$!}"
    end
  }
  result
end


module Test::Unit::RunCount - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Test::Unit::RunCount

In Files

  • lib/test/unit.rb

Public Class Methods

have_run?() click to toggle source
# File lib/test/unit.rb, line 15
def self.have_run?
  @@run_count.nonzero?
end
run_once() { || ... } click to toggle source
# File lib/test/unit.rb, line 24
def run_once
  return if have_run?
  return if $! # don't run if there was an exception
  yield
end

Public Instance Methods

run(*) click to toggle source
# File lib/test/unit.rb, line 19
def run(*)
  @@run_count += 1
  super
end


class Test::Unit::Runner - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Test::Unit::Runner

In Files

  • lib/test/unit.rb

Parent

MiniTest::Unit

Included Modules

  • Test::Unit::Options
  • Test::Unit::GlobOption
  • Test::Unit::LoadPathOption
  • Test::Unit::GCStressOption
  • Test::Unit::RunCount

Public Class Methods

autorun() click to toggle source
# File lib/test/unit.rb, line 363
def self.autorun
  at_exit {
    Test::Unit::RunCount.run_once {
      exit(Test::Unit::Runner.new.run(ARGV) || true)
    } unless @@stop_auto_run
  } unless @@installed_at_exit
  @@installed_at_exit = true
end

Public Instance Methods

_prepare_run(suites, type) click to toggle source
# File lib/test/unit.rb, line 676
def _prepare_run(suites, type)
  options[:job_status] ||= :replace if @tty && !@verbose
  case options[:color]
  when :always
    color = true
  when :auto, nil
    color = @options[:job_status] == :replace && /dumb/ !~ ENV["TERM"]
  else
    color = false
  end
  if color
    # dircolors-like style
    colors = (colors = ENV['TEST_COLORS']) ? Hash[colors.scan(/(\w+)=([^:]*)/)] : {}
    @passed_color = "\e[#{colors["pass"] || "32"}m"
    @failed_color = "\e[#{colors["fail"] || "31"}m"
    @skipped_color = "\e[#{colors["skip"] || "33"}m"
    @reset_color = "\e[m"
  else
    @passed_color = @failed_color = @skipped_color = @reset_color = ""
  end
  if color or @options[:job_status] == :replace
    @verbose = !options[:parallel]
    @output = StatusLineOutput.new(self)
  end
  if /\A\/(.*)\/\z/ =~ (filter = options[:filter])
    filter = Regexp.new($1)
  end
  type = "#{type}_methods"
  total = if filter
            suites.inject(0) {|n, suite| n + suite.send(type).grep(filter).size}
          else
            suites.inject(0) {|n, suite| n + suite.send(type).size}
          end
  @test_count = 0
  @total_tests = total.to_s(10)
end
_print(s) click to toggle source
# File lib/test/unit.rb, line 723
def _print(s); $stdout.print(s); end
_run_parallel(suites, type, result) click to toggle source
# File lib/test/unit.rb, line 564
def _run_parallel suites, type, result
  if @options[:parallel] < 1
    warn "Error: parameter of -j option should be greater than 0."
    return
  end

  # Require needed things for parallel running
  require 'thread'
  require 'timeout'
  @tasks = @files.dup # Array of filenames.
  @need_quit = false
  @dead_workers = []  # Array of dead workers.
  @warnings = []
  @total_tests = @tasks.size.to_s(10)
  rep = [] # FIXME: more good naming

  @workers      = [] # Array of workers.
  @workers_hash = {} # out-IO => worker
  @ios          = [] # Array of worker IOs
  begin
    # Thread: watchdog
    watchdog = start_watchdog

    @options[:parallel].times {launch_worker}

    while _io = IO.select(@ios)[0]
      break if _io.any? do |io|
        @need_quit or
          (deal(io, type, result, rep).nil? and
           !@workers.any? {|x| [:running, :prepare].include? x.status})
      end
    end
  rescue Interrupt => ex
    @interrupt = ex
    return result
  ensure
    watchdog.kill if watchdog
    if @interrupt
      @ios.select!{|x| @workers_hash[x].status == :running }
      while !@ios.empty? && (__io = IO.select(@ios,[],[],10))
        __io[0].reject! {|io| deal(io, type, result, rep, true)}
      end
    end

    quit_workers

    unless @interrupt || !@options[:retry] || @need_quit
      @options[:parallel] = false
      suites, rep = rep.partition {|r| r[:testcase] && r[:file] && r[:report].any? {|e| !e[2].is_a?(MiniTest::Skip)}}
      suites.map {|r| r[:file]}.uniq.each {|file| require file}
      suites.map! {|r| eval("::"+r[:testcase])}
      del_status_line or puts
      unless suites.empty?
        puts "Retrying..."
        _run_suites(suites, type)
      end
    end
    unless @options[:retry]
      del_status_line or puts
    end
    unless rep.empty?
      rep.each do |r|
        r[:report].each do |f|
          puke(*f) if f
        end
      end
      if @options[:retry]
        @errors   += rep.map{|x| x[:result][0] }.inject(:+)
        @failures += rep.map{|x| x[:result][1] }.inject(:+)
        @skips    += rep.map{|x| x[:result][2] }.inject(:+)
      end
    end
    unless @warnings.empty?
      warn ""
      @warnings.uniq! {|w| w[1].message}
      @warnings.each do |w|
        warn "#{w[0]}: #{w[1].message} (#{w[1].class})"
      end
      warn ""
    end
  end
end
_run_suites(suites, type) click to toggle source
# File lib/test/unit.rb, line 647
def _run_suites suites, type
  _prepare_run(suites, type)
  @interrupt = nil
  result = []
  GC.start
  if @options[:parallel]
    _run_parallel suites, type, result
  else
    suites.each {|suite|
      begin
        result << _run_suite(suite, type)
      rescue Interrupt => e
        @interrupt = e
        break
      end
    }
  end
  report.reject!{|r| r.start_with? "Skipped:" } if @options[:hide_skip]
  report.sort_by!{|r| r.start_with?("Skipped:") ? 0 :                             (r.start_with?("Failure:") ? 1 : 2) }
  result
end
add_status(line) click to toggle source
# File lib/test/unit.rb, line 425
def add_status(line)
  unless @options[:job_status] == :replace
    print(line)
    return
  end
  @status_line_size ||= 0
  line = line[0...(terminal_width-@status_line_size)]
  print line
  $stdout.flush
  @status_line_size += line.size
end
after_worker_down(worker, e=nil, c=false) click to toggle source
# File lib/test/unit.rb, line 372
def after_worker_down(worker, e=nil, c=false)
  return unless @options[:parallel]
  return if @interrupt
  warn e if e
  @need_quit = true
  warn ""
  warn "Some worker was crashed. It seems ruby interpreter's bug"
  warn "or, a bug of test/unit/parallel.rb. try again without -j"
  warn "option."
  warn ""
  STDERR.flush
  exit c
end
after_worker_quit(worker) click to toggle source
# File lib/test/unit.rb, line 449
def after_worker_quit(worker)
  return unless @options[:parallel]
  return if @interrupt
  @workers.delete(worker)
  @dead_workers << worker
  @ios = @workers.map(&:io)
end
deal(io, type, result, rep, shutting_down = false) click to toggle source
# File lib/test/unit.rb, line 521
def deal(io, type, result, rep, shutting_down = false)
  worker = @workers_hash[io]
  case worker.read
  when /^okay$/
    worker.status = :running
    jobs_status
  when /^ready(!)?$/
    bang = $1
    worker.status = :ready

    return nil unless task = @tasks.shift
    if @options[:separate] and not bang
      worker.quit
      worker = add_worker
    end
    worker.run(task, type)
    @test_count += 1

    jobs_status
  when /^done (.+?)$/
    r = Marshal.load($1.unpack("m")[0])
    result << r[0..1] unless r[0..1] == [nil,nil]
    rep    << {file: worker.real_file, report: r[2], result: r[3], testcase: r[5]}
    $:.push(*r[4]).uniq!
    return true
  when /^p (.+?)$/
    del_jobs_status
    print $1.unpack("m")[0]
    jobs_status if @options[:job_status] == :replace
  when /^after (.+?)$/
    @warnings << Marshal.load($1.unpack("m")[0])
  when /^bye (.+?)$/
    after_worker_down worker, Marshal.load($1.unpack("m")[0])
  when /^bye$/, nil
    if shutting_down || worker.quit_called
      after_worker_quit worker
    else
      after_worker_down worker
    end
  end
  return false
end
del_jobs_status() click to toggle source
# File lib/test/unit.rb, line 444
def del_jobs_status
  return unless @options[:job_status] == :replace && @status_line_size.nonzero?
  del_status_line
end
del_status_line() click to toggle source
# File lib/test/unit.rb, line 400
def del_status_line
  @status_line_size ||= 0
  unless @options[:job_status] == :replace
    $stdout.puts
    return
  end
  print "\r"+" "*@status_line_size+"\r"
  $stdout.flush
  @status_line_size = 0
end
delete_worker(worker) click to toggle source
# File lib/test/unit.rb, line 473
def delete_worker(worker)
  @workers_hash.delete worker.io
  @workers.delete worker
  @ios.delete worker.io
end
failed(s) click to toggle source
# File lib/test/unit.rb, line 726
def failed(s)
  sep = "\n"
  @report_count ||= 0
  report.each do |msg|
    if msg.start_with? "Skipped:"
      if @options[:hide_skip]
        del_status_line
        next
      end
      color = @skipped_color
    else
      color = @failed_color
    end
    msg = msg.split(/$/, 2)
    $stdout.printf("%s%s%3d) %s%s%s\n",
                   sep, color, @report_count += 1,
                   msg[0], @reset_color, msg[1])
    sep = nil
  end
  report.clear
end
jobs_status() click to toggle source
# File lib/test/unit.rb, line 437
def jobs_status
  return unless @options[:job_status]
  puts "" unless @options[:verbose] or @options[:job_status] == :replace
  status_line = @workers.map(&:to_s).join(" ")
  update_status(status_line) or (puts; nil)
end
launch_worker() click to toggle source
# File lib/test/unit.rb, line 457
def launch_worker
  begin
    worker = Worker.launch(@options[:ruby],@args)
  rescue => e
    abort "ERROR: Failed to launch job process - #{e.class}: #{e.message}"
  end
  worker.hook(:dead) do |w,info|
    after_worker_quit w
    after_worker_down w, *info if !info.empty? && !worker.quit_called
  end
  @workers << worker
  @ios << worker.io
  @workers_hash[worker.io] = worker
  worker
end
new_test(s) click to toggle source
# File lib/test/unit.rb, line 713
def new_test(s)
  @test_count += 1
  update_status(s)
end
output() click to toggle source
# File lib/test/unit.rb, line 672
def output
  (@output ||= nil) || super
end
puke(klass, meth, e) click to toggle source

Overriding of MiniTest::Unit#puke

# File lib/test/unit.rb, line 749
def puke klass, meth, e
  # TODO:
  #   this overriding is for minitest feature that skip messages are
  #   hidden when not verbose (-v), note this is temporally.
  n = report.size
  rep = super
  if MiniTest::Skip === e and /no message given\z/ =~ e.message
    report.slice!(n..-1)
    rep = "."
  end
  rep
end
put_status(line) click to toggle source
# File lib/test/unit.rb, line 411
def put_status(line)
  unless @options[:job_status] == :replace
    print(line)
    return
  end
  @status_line_size ||= 0
  del_status_line
  $stdout.flush
  line = line[0...terminal_width]
  print line
  $stdout.flush
  @status_line_size = line.size
end
quit_workers() click to toggle source
# File lib/test/unit.rb, line 479
def quit_workers
  return if @workers.empty?
  @workers.reject! do |worker|
    begin
      timeout(1) do
        worker.quit
      end
    rescue Errno::EPIPE
    rescue Timeout::Error
    end
    worker.close
  end

  return if @workers.empty?
  begin
    timeout(0.2 * @workers.size) do
      Process.waitall
    end
  rescue Timeout::Error
    @workers.each do |worker|
      worker.kill
    end
    @worker.clear
  end
end
run(*args) click to toggle source
# File lib/test/unit.rb, line 773
def run(*args)
  result = super
  puts "\nruby -v: #{RUBY_DESCRIPTION}"
  result
end
start_watchdog() click to toggle source
# File lib/test/unit.rb, line 505
def start_watchdog
  Thread.new do
    while stat = Process.wait2
      break if @interrupt # Break when interrupt
      pid, stat = stat
      w = (@workers + @dead_workers).find{|x| pid == x.pid }
      next unless w
      w = w.dup
      if w.status != :quit && !w.quit_called?
        # Worker down
        w.died(nil, !stat.signaled? && stat.exitstatus)
      end
    end
  end
end
status(*args) click to toggle source
# File lib/test/unit.rb, line 767
def status(*args)
  result = super
  raise @interrupt if @interrupt
  result
end
succeed() click to toggle source
# File lib/test/unit.rb, line 724
def succeed; del_status_line; end
terminal_width() click to toggle source
# File lib/test/unit.rb, line 386
def terminal_width
  unless @terminal_width ||= nil
    begin
      require 'io/console'
      width = $stdout.winsize[1]
    rescue LoadError, NoMethodError, Errno::ENOTTY, Errno::EBADF
      width = ENV["COLUMNS"].to_i.nonzero? || 80
    end
    width -= 1 if /mswin|mingw/ =~ RUBY_PLATFORM
    @terminal_width = width
  end
  @terminal_width
end
update_status(s) click to toggle source
# File lib/test/unit.rb, line 718
def update_status(s)
  count = @test_count.to_s(10).rjust(@total_tests.size)
  put_status("#{@passed_color}[#{count}/#{@total_tests}]#{@reset_color} #{s}")
end


class Test::Unit::Runner::Worker - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Test::Unit::Runner::Worker

In Files

  • lib/test/unit.rb

Parent

Object

Attributes

file[RW]
io[R]
loadpath[RW]
pid[R]
quit_called[R]
real_file[RW]
status[RW]

Public Class Methods

launch(ruby,args=[]) click to toggle source
# File lib/test/unit.rb, line 263
def self.launch(ruby,args=[])
  io = IO.popen([*ruby,
                "#{File.dirname(__FILE__)}/unit/parallel.rb",
                *args], "rb+")
  new(io, io.pid, :waiting)
end
new(io, pid, status) click to toggle source
# File lib/test/unit.rb, line 272
def initialize(io, pid, status)
  @io = io
  @pid = pid
  @status = status
  @file = nil
  @real_file = nil
  @loadpath = []
  @hooks = {}
  @quit_called = false
end

Public Instance Methods

close() click to toggle source
# File lib/test/unit.rb, line 314
def close
  @io.close unless @io.closed?
  self
rescue IOError
end
died(*additional) click to toggle source
# File lib/test/unit.rb, line 332
def died(*additional)
  @status = :quit
  @io.close

  call_hook(:dead,*additional)
end
hook(id,&block) click to toggle source
# File lib/test/unit.rb, line 303
def hook(id,&block)
  @hooks[id] ||= []
  @hooks[id] << block
  self
end
kill() click to toggle source
# File lib/test/unit.rb, line 327
def kill
  Process.kill(:KILL, @pid)
rescue Errno::ESRCH
end
puts(*args) click to toggle source
# File lib/test/unit.rb, line 283
def puts(*args)
  @io.puts(*args)
end
quit() click to toggle source
# File lib/test/unit.rb, line 320
def quit
  return if @io.closed?
  @quit_called = true
  @io.puts "quit"
  @io.close
end
read() click to toggle source
# File lib/test/unit.rb, line 309
def read
  res = (@status == :quit) ? @io.read : @io.gets
  res && res.chomp
end
run(task,type) click to toggle source
# File lib/test/unit.rb, line 287
def run(task,type)
  @file = File.basename(task, ".rb")
  @real_file = task
  begin
    puts "loadpath #{[Marshal.dump($:-@loadpath)].pack("m0")}"
    @loadpath = $:.dup
    puts "run #{task} #{type}"
    @status = :prepare
  rescue Errno::EPIPE
    died
  rescue IOError
    raise unless ["stream closed","closed stream"].include? $!.message
    died
  end
end
to_s() click to toggle source
# File lib/test/unit.rb, line 339
def to_s
  if @file
    "#{@pid}=#{@file}"
  else
    "#{@pid}:#{@status.to_s.ljust(7)}"
  end
end


class Test::Unit::StatusLineOutput - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Test::Unit::StatusLineOutput

In Files

  • lib/test/unit.rb

Parent

Struct.new(:runner)

Public Instance Methods

method_missing(*a, &b) click to toggle source
# File lib/test/unit.rb, line 783
def method_missing(*a, &b) $stdout.__send__(*a, &b) end
print(s) click to toggle source
# File lib/test/unit.rb, line 785
def print(s)
  case s
  when /\A(.*\#.*) = \z/
    runner.new_test($1)
  when /\A(.* s) = \z/
    runner.add_status(" = "+$1.chomp)
  when /\A\.+\z/
    runner.succeed
  when /\A[EFS]\z/
    runner.failed(s)
  else
    $stdout.print(s)
  end
end
puts(*a) click to toggle source
# File lib/test/unit.rb, line 781
def puts(*a) $stdout.puts(*a) unless a.empty? end
respond_to_missing?(*a) click to toggle source
# File lib/test/unit.rb, line 782
def respond_to_missing?(*a) $stdout.respond_to?(*a) end


class Test::Unit::TestCase - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Test::Unit::TestCase

In Files

  • lib/minitest/unit.rb
  • lib/test/unit/parallel.rb
  • lib/test/unit/testcase.rb

Parent

MiniTest::Unit::TestCase

Included Modules

  • Test::Unit::Assertions

Public Class Methods

method_added(name) click to toggle source
# File lib/test/unit/testcase.rb, line 24
def self.method_added(name)
  return unless name.to_s.start_with?("test_")
  @test_methods ||= {}
  if @test_methods[name]
    warn "test/unit warning: method #{ self }##{ name } is redefined"
  end
  @test_methods[name] = true
end
test_order() click to toggle source
# File lib/test/unit/testcase.rb, line 20
def self.test_order
  :sorted
end

Public Instance Methods

on_parallel_worker?() click to toggle source
# File lib/test/unit/parallel.rb, line 175
def on_parallel_worker?
  true
end
run(runner) click to toggle source
# File lib/test/unit/testcase.rb, line 15
def run runner
  @options = runner.options
  super runner
end


class Test::Unit::Worker - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Test::Unit::Worker

In Files

  • lib/test/unit/parallel.rb

Parent

Runner

Public Instance Methods

_report(res, *args) click to toggle source
# File lib/test/unit/parallel.rb, line 152
def _report(res, *args)
  res = "#{res} #{args.pack("m0")}" unless args.empty?
  @stdout.puts(res)
end
_run_suite(suite, type) click to toggle source
# File lib/test/unit/parallel.rb, line 27
def _run_suite(suite, type)
  @partial_report = []
  orig_testout = MiniTest::Unit.output
  i,o = IO.pipe

  MiniTest::Unit.output = o
  orig_stdin, orig_stdout = $stdin, $stdout

  th = Thread.new do
    begin
      while buf = (self.verbose ? i.gets : i.read(5))
        _report "p", buf
      end
    rescue IOError
    rescue Errno::EPIPE
    end
  end

  e, f, s = @errors, @failures, @skips

  begin
    result = orig_run_suite(suite, type)
  rescue Interrupt
    @need_exit = true
    result = [nil,nil]
  end

  MiniTest::Unit.output = orig_testout
  $stdin = orig_stdin
  $stdout = orig_stdout

  o.close
  begin
    th.join
  rescue IOError
    raise unless ["stream closed","closed stream"].include? $!.message
  end
  i.close

  result << @partial_report
  @partial_report = nil
  result << [@errors-e,@failures-f,@skips-s]
  result << ($: - @old_loadpath)
  result << suite.name

  begin
    _report "done", Marshal.dump(result)
  rescue Errno::EPIPE; end
  return result
ensure
  MiniTest::Unit.output = orig_stdout
  $stdin = orig_stdin
  $stdout = orig_stdout
  o.close if o && !o.closed?
  i.close if i && !i.closed?
end
_run_suites(suites, type) click to toggle source
# File lib/test/unit/parallel.rb, line 21
def _run_suites(suites, type)
  suites.map do |suite|
    _run_suite(suite, type)
  end
end
increment_io(orig) click to toggle source
# File lib/test/unit/parallel.rb, line 15
def increment_io(orig)
  *rest, io = 32.times.inject([orig.dup]){|ios, | ios << ios.last.dup }
  rest.each(&:close)
  io
end
puke(klass, meth, e) click to toggle source
# File lib/test/unit/parallel.rb, line 157
def puke(klass, meth, e)
  if e.is_a?(MiniTest::Skip)
    new_e = MiniTest::Skip.new(e.message)
    new_e.set_backtrace(e.backtrace)
    e = new_e
  end
  @partial_report << [klass.name, meth, e.is_a?(MiniTest::Assertion) ? e : ProxyError.new(e)]
  super
end
run(args = []) click to toggle source
# File lib/test/unit/parallel.rb, line 84
def run(args = [])
  process_args args
  @@stop_auto_run = true
  @opts = @options.dup
  @need_exit = false

  @old_loadpath = []
  begin
    begin
      @stdout = increment_io(STDOUT)
      @stdin = increment_io(STDIN)
    rescue
      exit 2
    end
    exit 2 unless @stdout && @stdin

    @stdout.sync = true
    _report "ready!"
    while buf = @stdin.gets
      case buf.chomp
      when /^loadpath (.+?)$/
        @old_loadpath = $:.dup
        $:.push(*Marshal.load($1.unpack("m")[0].force_encoding("ASCII-8BIT"))).uniq!
      when /^run (.+?) (.+?)$/
        _report "okay"

        @options = @opts.dup
        suites = MiniTest::Unit::TestCase.test_suites

        begin
          require $1
        rescue LoadError
          _report "after", Marshal.dump([$1, ProxyError.new($!)])
          _report "ready"
          next
        end
        _run_suites MiniTest::Unit::TestCase.test_suites-suites, $2.to_sym

        if @need_exit
          begin
            _report "bye"
          rescue Errno::EPIPE; end
          exit
        else
          _report "ready"
        end
      when /^quit$/
        begin
          _report "bye"
        rescue Errno::EPIPE; end
        exit
      end
    end
  rescue Errno::EPIPE
  rescue Exception => e
    begin
      trace = e.backtrace
      err = ["#{trace.shift}: #{e.message} (#{e.class})"] + trace.map{|t| t.prepend("\t") }

      _report "bye", Marshal.dump(err.join("\n"))
    rescue Errno::EPIPE;end
    exit
  ensure
    @stdin.close if @stdin
    @stdout.close if @stdout
  end
end


class ThreadError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class ThreadError

In Files

  • lib/thread.rb

Parent

StandardError


class Time - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Time

time.rb

When 'time' is required, Time is extended with additional methods for parsing and converting Times.

Features

This library extends the Time class with the following conversions between date strings and Time objects:

  • date-time defined by RFC 2822

  • HTTP-date defined by RFC 2616

  • dateTime defined by XML Schema Part 2: Datatypes (ISO 8601)

  • various formats handled by Date._parse

  • custom formats handled by Date._strptime

Examples

All examples assume you have loaded Time with:

require 'time'

All of these examples were done using the EST timezone which is GMT-5.

Converting to a String

t = Time.now
t.iso8601  # => "2011-10-05T22:26:12-04:00"
t.rfc2822  # => "Wed, 05 Oct 2011 22:26:12 -0400"
t.httpdate # => "Thu, 06 Oct 2011 02:26:12 GMT"

::parse

parse takes a string representation of a Time and attempts to parse it using a heuristic.

Date.parse("2010-10-31") #=> 2010-10-31 00:00:00 -0500

Any missing pieces of the date are inferred based on the current date.

# assuming the current date is "2011-10-31"
Time.parse("12:00") #=> 2011-10-31 12:00:00 -0500

We can change the date used to infer our missing elements by passing a second object that responds to mon, day and year, such as Date, Time or DateTime. We can also use our own object.

class MyDate
  attr_reader :mon, :day, :year

  def initialize(mon, day, year)
    @mon, @day, @year = mon, day, year
  end
end

d  = Date.parse("2010-10-28")
t  = Time.parse("2010-10-29")
dt = DateTime.parse("2010-10-30")
md = MyDate.new(10,31,2010)

Time.parse("12:00", d)  #=> 2010-10-28 12:00:00 -0500
Time.parse("12:00", t)  #=> 2010-10-29 12:00:00 -0500
Time.parse("12:00", dt) #=> 2010-10-30 12:00:00 -0500
Time.parse("12:00", md) #=> 2010-10-31 12:00:00 -0500

parse also accepts an optional block. You can use this block to specify how to handle the year component of the date. This is specifically designed for handling two digit years. For example, if you wanted to treat all two digit years prior to 70 as the year 2000+ you could write this:

Time.parse("01-10-31") {|year| year + (year < 70 ? 2000 : 1900)}
#=> 2001-10-31 00:00:00 -0500
Time.parse("70-10-31") {|year| year + (year < 70 ? 2000 : 1900)}
#=> 1970-10-31 00:00:00 -0500

::strptime

strptime works similar to parse except that instead of using a heuristic to detect the format of the input string, you provide a second argument that is describes the format of the string. For example:

Time.strptime("2000-10-31", "%Y-%m-%d") #=> 2000-10-31 00:00:00 -0500

Time serialization/deserialization

In Files

  • lib/rake/ext/time.rb
  • lib/rss/rss.rb
  • lib/time.rb
  • ext/date/date_core.c
  • ext/json/lib/json/add/time.rb

Parent

Object

Constants

CommonYearMonthDays
LeapYearMonthDays
MonthValue
RFC2822_DAY_NAME
RFC2822_MONTH_NAME

Public Class Methods

httpdate(date) click to toggle source

Parses date as an HTTP-date defined by RFC 2616 and converts it to a Time object.

ArgumentError is raised if date is not compliant with RFC 2616 or if the Time class cannot represent specified date.

See httpdate for more information on this format.

You must require 'time' to use this method.

# File lib/time.rb, line 476
def httpdate(date)
  if /\A\s*
      (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\x20
      (\d{2})\x20
      (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\x20
      (\d{4})\x20
      (\d{2}):(\d{2}):(\d{2})\x20
      GMT
      \s*\z/x =~ date
    self.rfc2822(date)
  elsif /\A\s*
         (?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\x20
         (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d)\x20
         (\d\d):(\d\d):(\d\d)\x20
         GMT
         \s*\z/x =~ date
    year = $3.to_i
    if year < 50
      year += 2000
    else
      year += 1900
    end
    self.utc(year, $2, $1.to_i, $4.to_i, $5.to_i, $6.to_i)
  elsif /\A\s*
         (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\x20
         (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\x20
         (\d\d|\x20\d)\x20
         (\d\d):(\d\d):(\d\d)\x20
         (\d{4})
         \s*\z/x =~ date
    self.utc($6.to_i, MonthValue[$1.upcase], $2.to_i,
             $3.to_i, $4.to_i, $5.to_i)
  else
    raise ArgumentError.new("not RFC 2616 compliant date: #{date.inspect}")
  end
end
iso8601(date) click to toggle source
Alias for: xmlschema
json_create(object) click to toggle source

Deserializes JSON string by converting time since epoch to Time

# File ext/json/lib/json/add/time.rb, line 9
def self.json_create(object)
  if usec = object.delete('u') # used to be tv_usec -> tv_nsec
    object['n'] = usec * 1000
  end
  if instance_methods.include?(:tv_nsec)
    at(object['s'], Rational(object['n'], 1000))
  else
    at(object['s'], object['n'] / 1000)
  end
end
parse(date, now=self.now) { |year| ... } click to toggle source

Parses date using Date._parse and converts it to a Time object.

If a block is given, the year described in date is converted by the block. For example:

Time.parse(...) {|y| 0 <= y && y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}

If the upper components of the given time are broken or missing, they are supplied with those of now. For the lower components, the minimum values (1 or 0) are assumed if broken or missing. For example:

# Suppose it is "Thu Nov 29 14:33:20 GMT 2001" now and
# your time zone is GMT:
now = Time.parse("Thu Nov 29 14:33:20 GMT 2001")
Time.parse("16:30", now)     #=> 2001-11-29 16:30:00 +0900
Time.parse("7/23", now)      #=> 2001-07-23 00:00:00 +0900
Time.parse("Aug 31", now)    #=> 2001-08-31 00:00:00 +0900
Time.parse("Aug 2000", now)  #=> 2000-08-01 00:00:00 +0900

Since there are numerous conflicts among locally defined time zone abbreviations all over the world, this method is not intended to understand all of them. For example, the abbreviation “CST” is used variously as:

-06:00 in America/Chicago,
-05:00 in America/Havana,
+08:00 in Asia/Harbin,
+09:30 in Australia/Darwin,
+10:30 in Australia/Adelaide,
etc.

Based on this fact, this method only understands the time zone abbreviations described in RFC 822 and the system time zone, in the order named. (i.e. a definition in RFC 822 overrides the system time zone definition.) The system time zone is taken from Time.local(year, 1, 1).zone and Time.local(year, 7, 1).zone. If the extracted time zone abbreviation does not match any of them, it is ignored and the given time is regarded as a local time.

ArgumentError is raised if Date._parse cannot extract information from date or if the Time class cannot represent specified date.

This method can be used as a fail-safe for other parsing methods as:

Time.rfc2822(date) rescue Time.parse(date)
Time.httpdate(date) rescue Time.parse(date)
Time.xmlschema(date) rescue Time.parse(date)

A failure of ::parse should be checked, though.

You must require 'time' to use this method.

# File lib/time.rb, line 323
def parse(date, now=self.now)
  comp = !block_given?
  d = Date._parse(date, comp)
  if !d[:year] && !d[:mon] && !d[:mday] && !d[:hour] && !d[:min] && !d[:sec] && !d[:sec_fraction]
    raise ArgumentError, "no time information in #{date.inspect}"
  end
  year = d[:year]
  year = yield(year) if year && !comp
  make_time(year, d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now)
end
rfc2822(date) click to toggle source

Parses date as date-time defined by RFC 2822 and converts it to a Time object. The format is identical to the date format defined by RFC 822 and updated by RFC 1123.

ArgumentError is raised if date is not compliant with RFC 2822 or if the Time class cannot represent specified date.

See rfc2822 for more information on this format.

You must require 'time' to use this method.

# File lib/time.rb, line 425
def rfc2822(date)
  if /\A\s*
      (?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*,\s*)?
      (\d{1,2})\s+
      (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+
      (\d{2,})\s+
      (\d{2})\s*
      :\s*(\d{2})\s*
      (?::\s*(\d{2}))?\s+
      ([+-]\d{4}|
       UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT|[A-IK-Z])/x =~ date
    # Since RFC 2822 permit comments, the regexp has no right anchor.
    day = $1.to_i
    mon = MonthValue[$2.upcase]
    year = $3.to_i
    hour = $4.to_i
    min = $5.to_i
    sec = $6 ? $6.to_i : 0
    zone = $7

    # following year completion is compliant with RFC 2822.
    year = if year < 50
             2000 + year
           elsif year < 1000
             1900 + year
           else
             year
           end

    year, mon, day, hour, min, sec =
      apply_offset(year, mon, day, hour, min, sec, zone_offset(zone))
    t = self.utc(year, mon, day, hour, min, sec)
    t.localtime if !zone_utc?(zone)
    t
  else
    raise ArgumentError.new("not RFC 2822 compliant date: #{date.inspect}")
  end
end
Also aliased as: rfc822
rfc822(date) click to toggle source
Alias for: rfc2822
strptime(date, format, now=self.now) { |year| ... } click to toggle source

Parses date using Date._strptime and converts it to a Time object.

If a block is given, the year described in date is converted by the block. For example:

Time.strptime(...) {|y| y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}

Below is a list of the formating options:

%a

The abbreviated weekday name (“Sun”)

%A

The full weekday name (“Sunday”)

%b

The abbreviated month name (“Jan”)

%B

The full month name (“January”)

%c

The preferred local date and time representation

%C

Century (20 in 2009)

%d

Day of the month (01..31)

%D

Date (%m/%d/%y)

%e

Day of the month, blank-padded ( 1..31)

%F

Equivalent to %Y-%m-%d (the ISO 8601 date format)

%h

Equivalent to %b

%H

Hour of the day, 24-hour clock (00..23)

%I

Hour of the day, 12-hour clock (01..12)

%j

Day of the year (001..366)

%k

hour, 24-hour clock, blank-padded ( 0..23)

%l

hour, 12-hour clock, blank-padded ( 0..12)

%L

Millisecond of the second (000..999)

%m

Month of the year (01..12)

%M

Minute of the hour (00..59)

%n

Newline (n)

%N

Fractional seconds digits, default is 9 digits (nanosecond)

%3N

millisecond (3 digits)

%6N

microsecond (6 digits)

%9N

nanosecond (9 digits)

%p

Meridian indicator (“AM” or “PM”)

%P

Meridian indicator (“am” or “pm”)

%r

time, 12-hour (same as %I:%M:%S %p)

%R

time, 24-hour (%H:%M)

%s

Number of seconds since 1970-01-01 00:00:00 UTC.

%S

Second of the minute (00..60)

%t

Tab character (t)

%T

time, 24-hour (%H:%M:%S)

%u

Day of the week as a decimal, Monday being 1. (1..7)

%U

Week number of the current year, starting with the first Sunday as the first day of the first week (00..53)

%v

VMS date (%e-%b-%Y)

%V

Week number of year according to ISO 8601 (01..53)

%W

Week number of the current year, starting with the first Monday as the first day of the first week (00..53)

%w

Day of the week (Sunday is 0, 0..6)

%x

Preferred representation for the date alone, no time

%X

Preferred representation for the time alone, no date

%y

Year without a century (00..99)

%Y

Year with century

%z

Time zone as hour offset from UTC (e.g. +0900)

%Z

Time zone name

%%

Literal “%” character

# File lib/time.rb, line 392
def strptime(date, format, now=self.now)
  d = Date._strptime(date, format)
  raise ArgumentError, "invalid strptime format - `#{format}'" unless d
  if seconds = d[:seconds]
    if offset = d[:offset]
      Time.at(seconds).localtime(offset)
    else
      Time.at(seconds)
    end
  else
    year = d[:year]
    year = yield(year) if year && block_given?
    make_time(year, d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now)
  end
end
w3cdtf(date) click to toggle source
# File lib/rss/rss.rb, line 6
def w3cdtf(date)
  if /\A\s*
      (-?\d+)-(\d\d)-(\d\d)
      (?:T
      (\d\d):(\d\d)(?::(\d\d))?
      (\.\d+)?
      (Z|[+-]\d\d:\d\d)?)?
      \s*\z/x =~ date and (($5 and $8) or (!$5 and !$8))
    datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i]
    usec = 0
    usec = $7.to_f * 1000000 if $7
    zone = $8
    if zone
      off = zone_offset(zone, datetime[0])
      datetime = apply_offset(*(datetime + [off]))
      datetime << usec
      time = Time.utc(*datetime)
      time.localtime unless zone_utc?(zone)
      time
    else
      datetime << usec
      Time.local(*datetime)
    end
  else
    raise ArgumentError.new("invalid date: #{date.inspect}")
  end
end
xmlschema(date) click to toggle source

Parses date as a dateTime defined by the XML Schema and converts it to a Time object. The format is a restricted version of the format defined by ISO 8601.

ArgumentError is raised if date is not compliant with the format or if the Time class cannot represent specified date.

See xmlschema for more information on this format.

You must require 'time' to use this method.

# File lib/time.rb, line 525
def xmlschema(date)
  if /\A\s*
      (-?\d+)-(\d\d)-(\d\d)
      T
      (\d\d):(\d\d):(\d\d)
      (\.\d+)?
      (Z|[+-]\d\d:\d\d)?
      \s*\z/x =~ date
    year = $1.to_i
    mon = $2.to_i
    day = $3.to_i
    hour = $4.to_i
    min = $5.to_i
    sec = $6.to_i
    usec = 0
    if $7
      usec = Rational($7) * 1000000
    end
    if $8
      zone = $8
      year, mon, day, hour, min, sec =
        apply_offset(year, mon, day, hour, min, sec, zone_offset(zone))
      self.utc(year, mon, day, hour, min, sec, usec)
    else
      self.local(year, mon, day, hour, min, sec, usec)
    end
  else
    raise ArgumentError.new("invalid date: #{date.inspect}")
  end
end
Also aliased as: iso8601
zone_offset(zone, year=self.now.year) click to toggle source

Return the number of seconds the specified time zone differs from UTC.

Numeric time zones that include minutes, such as -10:00 or +1330 will work, as will simpler hour-only time zones like -10 or +13.

Textual time zones listed in ZoneOffset are also supported.

If the time zone does not match any of the above, zone_offset will check if the local time zone (both with and without potential Daylight Saving Time changes being in effect) matches zone. Specifying a value for year will change the year used to find the local time zone.

If zone_offset is unable to determine the offset, nil will be returned.

# File lib/time.rb, line 132
def zone_offset(zone, year=self.now.year)
  off = nil
  zone = zone.upcase
  if /\A([+-])(\d\d):?(\d\d)\z/ =~ zone
    off = ($1 == '-' ? -1 : 1) * ($2.to_i * 60 + $3.to_i) * 60
  elsif /\A[+-]\d\d\z/ =~ zone
    off = zone.to_i * 3600
  elsif ZoneOffset.include?(zone)
    off = ZoneOffset[zone] * 3600
  elsif ((t = self.local(year, 1, 1)).zone.upcase == zone rescue false)
    off = t.utc_offset
  elsif ((t = self.local(year, 7, 1)).zone.upcase == zone rescue false)
    off = t.utc_offset
  end
  off
end

Public Instance Methods

<=>(other) click to toggle source
# File lib/rake/ext/time.rb, line 8
def <=>(other)
  if Rake::EarlyTime === other
    - other.<=>(self)
  else
    rake_original_time_compare(other)
  end
end
Also aliased as: rake_original_time_compare
as_json(*) click to toggle source

Returns a hash, that will be turned into a JSON object and represent this object.

# File ext/json/lib/json/add/time.rb, line 22
def as_json(*)
  nanoseconds = [ tv_usec * 1000 ]
  respond_to?(:tv_nsec) and nanoseconds << tv_nsec
  nanoseconds = nanoseconds.max
  {
    JSON.create_id => self.class.name,
    's'            => tv_sec,
    'n'            => nanoseconds,
  }
end
httpdate() click to toggle source

Returns a string which represents the time as RFC 1123 date of HTTP-date defined by RFC 2616:

day-of-week, DD month-name CCYY hh:mm:ss GMT

Note that the result is always UTC (GMT).

You must require 'time' to use this method.

# File lib/time.rb, line 602
def httpdate
  t = dup.utc
  sprintf('%s, %02d %s %0*d %02d:%02d:%02d GMT',
    RFC2822_DAY_NAME[t.wday],
    t.day, RFC2822_MONTH_NAME[t.mon-1], t.year < 0 ? 5 : 4, t.year,
    t.hour, t.min, t.sec)
end
iso8601(fraction_digits=0) click to toggle source
Alias for: xmlschema
rake_original_time_compare(other) click to toggle source
Alias for: <=>
rfc2822() click to toggle source

Returns a string which represents the time as date-time defined by RFC 2822:

day-of-week, DD month-name CCYY hh:mm:ss zone

where zone is [+-]hhmm.

If self is a UTC time, -0000 is used as zone.

You must require 'time' to use this method.

# File lib/time.rb, line 569
def rfc2822
  sprintf('%s, %02d %s %0*d %02d:%02d:%02d ',
    RFC2822_DAY_NAME[wday],
    day, RFC2822_MONTH_NAME[mon-1], year < 0 ? 5 : 4, year,
    hour, min, sec) +
  if utc?
    '-0000'
  else
    off = utc_offset
    sign = off < 0 ? '-' : '+'
    sprintf('%s%02d%02d', sign, *(off.abs / 60).divmod(60))
  end
end
Also aliased as: rfc822
rfc822() click to toggle source
Alias for: rfc2822
to_date → date click to toggle source

Returns a Date object which denotes self.

static VALUE
time_to_date(VALUE self)
{
    VALUE y, nth, ret;
    int ry, m, d;

    y = f_year(self);
    m = FIX2INT(f_mon(self));
    d = FIX2INT(f_mday(self));

    decode_year(y, -1, &nth, &ry);

    ret = d_simple_new_internal(cDate,
                                nth, 0,
                                GREGORIAN,
                                ry, m, d,
                                HAVE_CIVIL);
    {
        get_d1(ret);
        set_sg(dat, DEFAULT_SG);
    }
    return ret;
}
to_datetime → datetime click to toggle source

Returns a DateTime object which denotes self.

static VALUE
time_to_datetime(VALUE self)
{
    VALUE y, sf, nth, ret;
    int ry, m, d, h, min, s, of;

    y = f_year(self);
    m = FIX2INT(f_mon(self));
    d = FIX2INT(f_mday(self));

    h = FIX2INT(f_hour(self));
    min = FIX2INT(f_min(self));
    s = FIX2INT(f_sec(self));
    if (s == 60)
        s = 59;

    sf = sec_to_ns(f_subsec(self));
    of = FIX2INT(f_utc_offset(self));

    decode_year(y, -1, &nth, &ry);

    ret = d_complex_new_internal(cDateTime,
                                 nth, 0,
                                 0, sf,
                                 of, DEFAULT_SG,
                                 ry, m, d,
                                 h, min, s,
                                 HAVE_CIVIL | HAVE_TIME);
    {
        get_d1(ret);
        set_sg(dat, DEFAULT_SG);
    }
    return ret;
}
to_json(*args) click to toggle source

Stores class name (Time) with number of seconds since epoch and number of microseconds for Time as JSON string

# File ext/json/lib/json/add/time.rb, line 35
def to_json(*args)
  as_json.to_json(*args)
end
to_time → time click to toggle source

Returns a copy of self as local mode.

static VALUE
time_to_time(VALUE self)
{
    return f_getlocal(self);
}
w3cdtf() click to toggle source
# File lib/rss/rss.rb, line 37
def w3cdtf
  if usec.zero?
    fraction_digits = 0
  else
    fraction_digits = Math.log10(usec.to_s.sub(/0*$/, '').to_i).floor + 1
  end
  xmlschema(fraction_digits)
end
xmlschema(fraction_digits=0) click to toggle source

Returns a string which represents the time as a dateTime defined by XML Schema:

CCYY-MM-DDThh:mm:ssTZD
CCYY-MM-DDThh:mm:ss.sssTZD

where TZD is Z or [+-]hh:mm.

If self is a UTC time, Z is used as TZD. [+-]hh:mm is used otherwise.

fractional_digits specifies a number of digits to use for fractional seconds. Its default value is 0.

You must require 'time' to use this method.

# File lib/time.rb, line 626
def xmlschema(fraction_digits=0)
  fraction_digits = fraction_digits.to_i
  s = strftime("%FT%T")
  if fraction_digits > 0
    s << strftime(".%#{fraction_digits}N")
  end
  s << (utc? ? 'Z' : strftime("%:z"))
end
Also aliased as: iso8601


module Timeout - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Timeout

Timeout long-running blocks

Synopsis

require 'timeout'
status = Timeout::timeout(5) {
  # Something that should be interrupted if it takes more than 5 seconds...
}

Description

Timeout provides a way to auto-terminate a potentially long-running operation if it hasn't finished in a fixed amount of time.

Previous versions didn't use a module for namespacing, however timeout is provided for backwards compatibility. You should prefer Timeout#timeout instead.

Copyright

Copyright

(C) 2000 Network Applied Communication Laboratory, Inc.

Copyright

(C) 2000 Information-technology Promotion Agency, Japan

In Files

  • lib/timeout.rb

Public Class Methods

timeout(sec, klass = nil) { |sec| ... } click to toggle source

Perform an operation in a block, raising an error if it takes longer than sec seconds to complete.

sec

Number of seconds to wait for the block to terminate. Any number may be used, including Floats to specify fractional seconds. A value of 0 or nil will execute the block without any timeout.

klass

Exception Class to raise if the block fails to terminate in sec seconds. Omitting will use the default, Timeout::Error

Returns the result of the block if the block completed before sec seconds, otherwise throws an exception, based on the value of klass.

Note that this is both a method of module Timeout, so you can include Timeout into your classes so they have a timeout method, as well as a module method, so you can call it directly as ::timeout.

# File lib/timeout.rb, line 51
def timeout(sec, klass = nil)   #:yield: +sec+
  return yield(sec) if sec == nil or sec.zero?
  exception = klass || Class.new(ExitException)
  begin
    begin
      x = Thread.current
      y = Thread.start {
        begin
          sleep sec
        rescue => e
          x.raise e
        else
          x.raise exception, "execution expired"
        end
      }
      return yield(sec)
    ensure
      if y
        y.kill
        y.join # make sure y is dead.
      end
    end
  rescue exception => e
    rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/
    (bt = e.backtrace).reject! {|m| rej =~ m}
    level = -caller(CALLER_OFFSET).size
    while THIS_FILE =~ bt[level]
      bt.delete_at(level)
      level += 1
    end
    raise if klass            # if exception class is specified, it
                              # would be expected outside.
    raise Error, e.message, e.backtrace
  end
end


class Tracer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Tracer

Outputs a source level execution trace of a Ruby program.

It does this by registering an event handler with Kernel#set_trace_func for processing incoming events. It also provides methods for filtering unwanted trace output (see ::add_filter, ::on, and ::off).

Example

Consider the following ruby script

class A
  def square(a)
    return a*a
  end
end

a = A.new
a.square(5)

Running the above script using ruby -r tracer example.rb will output the following trace to STDOUT (Note you can also explicitly require 'tracer')

#0:<internal:lib/rubygems/custom_require>:38:Kernel:<: -
#0:example.rb:3::-: class A
#0:example.rb:3::C: class A
#0:example.rb:4::-:   def square(a)
#0:example.rb:7::E: end
#0:example.rb:9::-: a = A.new
#0:example.rb:10::-: a.square(5)
#0:example.rb:4:A:>:   def square(a)
#0:example.rb:5:A:-:     return a*a
#0:example.rb:6:A:<:   end
 |  |         | |  |
 |  |         | |   ---------------------+ event
 |  |         |  ------------------------+ class
 |  |          --------------------------+ line
 |   ------------------------------------+ filename
  ---------------------------------------+ thread

Symbol table used for displaying incoming events:

+}+

call a C-language routine

+{+

return from a C-language routine

+>+

call a Ruby method

C

start a class or module definition

E

finish a class or module definition

-

execute code on a new line

+^+

raise an exception

+<+

return from a Ruby method

Copyright

by Keiju ISHITSUKA(keiju@ishitsuka.com)

In Files

  • lib/debug.rb
  • lib/tracer.rb

Parent

Object

Constants

EVENT_SYMBOL

Symbol table used for displaying trace information

Single

Reference to singleton instance of Tracer

Attributes

display_c_call[RW]

display C-routine calls in trace output (defaults to false)

display_c_call?[RW]

display C-routine calls in trace output (defaults to false)

display_process_id[RW]

display process id in trace output (defaults to false)

display_process_id?[RW]

display process id in trace output (defaults to false)

display_thread_id[RW]

display thread id in trace output (defaults to true)

display_thread_id?[RW]

display thread id in trace output (defaults to true)

stdout[RW]

output stream used to output trace (defaults to STDOUT)

stdout_mutex[R]

mutex lock used by tracer for displaying trace output

verbose[RW]

display additional debug information (defaults to false)

verbose?[RW]

display additional debug information (defaults to false)

Public Class Methods

add_filter(p = proc) click to toggle source

Used to filter unwanted trace output

Example which only outputs lines of code executed within the Kernel class:

Tracer.add_filter do |event, file, line, id, binding, klass, *rest|
  "Kernel" == klass.to_s
end

# File lib/tracer.rb, line 271
def Tracer.add_filter(p = proc)
  Single.add_filter(p)
end
off() click to toggle source

Disable tracing

# File lib/tracer.rb, line 244
def Tracer.off
  Single.off
end
on() { || ... } click to toggle source

Start tracing

Example

Tracer.on
# code to trace here
Tracer.off

You can also pass a block:

Tracer.on {
  # trace everything in this block
}
# File lib/tracer.rb, line 233
def Tracer.on
  if block_given?
    Single.on{yield}
  else
    Single.on
  end
end
set_get_line_procs(file_name, p = proc) click to toggle source

Register an event handler p which is called everytime a line in file_name is executed.

Example:

Tracer.set_get_line_procs("example.rb", lambda { |line|
  puts "line number executed is #{line}"
})

# File lib/tracer.rb, line 258
def Tracer.set_get_line_procs(file_name, p = proc)
  Single.set_get_line_procs(file_name, p)
end


class UDPSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class UDPSocket

UDPSocket represents a UDP/IP socket.

In Files

  • lib/resolv-replace.rb
  • ext/socket/udpsocket.c

Parent

IPSocket

Public Class Methods

new([address_family]) → socket click to toggle source

Creates a new UDPSocket object.

address_family should be an integer, a string or a symbol: Socket::AF_INET, “AF_INET”, :INET, etc.

UDPSocket.new                   #=> #<UDPSocket:fd 3>
UDPSocket.new(Socket::AF_INET6) #=> #<UDPSocket:fd 4>

static VALUE
udp_init(int argc, VALUE *argv, VALUE sock)
{
    VALUE arg;
    int family = AF_INET;
    int fd;

    rb_secure(3);
    if (rb_scan_args(argc, argv, "01", &arg) == 1) {
        family = rsock_family_arg(arg);
    }
    fd = rsock_socket(family, SOCK_DGRAM, 0);
    if (fd < 0) {
        rb_sys_fail("socket(2) - udp");
    }

    return rsock_init_sock(sock, fd);
}

Public Instance Methods

bind(host, port) click to toggle source

Binds udpsocket to host:port.

u1 = UDPSocket.new
u1.bind("127.0.0.1", 4913)
u1.send "message-to-self", 0, "127.0.0.1", 4913
p u1.recvfrom(10) #=> ["message-to", ["AF_INET", 4913, "localhost", "127.0.0.1"]]

# File lib/resolv-replace.rb, line 31
def bind(host, port)
  host = IPSocket.getaddress(host) if host != ""
  original_resolv_bind(host, port)
end
connect(host, port) click to toggle source

Connects udpsocket to host:port.

This makes possible to send without destination address.

u1 = UDPSocket.new
u1.bind("127.0.0.1", 4913)
u2 = UDPSocket.new
u2.connect("127.0.0.1", 4913)
u2.send "uuuu", 0
p u1.recvfrom(10) #=> ["uuuu", ["AF_INET", 33230, "localhost", "127.0.0.1"]]

# File lib/resolv-replace.rb, line 39
def connect(host, port)
  original_resolv_connect(IPSocket.getaddress(host), port)
end
recvfrom_nonblock(maxlen) → [mesg, sender_inet_addr] click to toggle source
recvfrom_nonblock(maxlen, flags) → [mesg, sender_inet_addr]

Receives up to maxlen bytes from udpsocket using recvfrom(2) after O_NONBLOCK is set for the underlying file descriptor. If maxlen is omitted, its default value is 65536. flags is zero or more of the MSG_ options. The first element of the results, mesg, is the data received. The second element, sender_inet_addr, is an array to represent the sender address.

When recvfrom(2) returns 0, Socket#recvfrom_nonblock returns an empty string as data. It means an empty packet.

Parameters

  • maxlen - the number of bytes to receive from the socket

  • flags - zero or more of the MSG_ options

Example

require 'socket'
s1 = UDPSocket.new
s1.bind("127.0.0.1", 0)
s2 = UDPSocket.new
s2.bind("127.0.0.1", 0)
s2.connect(*s1.addr.values_at(3,1))
s1.connect(*s2.addr.values_at(3,1))
s1.send "aaa", 0
begin # emulate blocking recvfrom
  p s2.recvfrom_nonblock(10)  #=> ["aaa", ["AF_INET", 33302, "localhost.localdomain", "127.0.0.1"]]
rescue IO::WaitReadable
  IO.select([s2])
  retry
end

Refer to Socket#recvfrom for the exceptions that may be thrown if the call to #recvfrom_nonblock fails.

#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure, including Errno::EWOULDBLOCK.

If the exception is Errno::EWOULDBLOCK or Errno::AGAIN, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying recvfrom_nonblock.

See

  • Socket#recvfrom

static VALUE
udp_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock)
{
    return rsock_s_recvfrom_nonblock(sock, argc, argv, RECV_IP);
}
send(mesg, flags, *rest) click to toggle source

Sends mesg via udpsocket.

flags should be a bitwise OR of Socket::MSG_* constants.

u1 = UDPSocket.new
u1.bind("127.0.0.1", 4913)

u2 = UDPSocket.new
u2.send "hi", 0, "127.0.0.1", 4913

mesg, addr = u1.recvfrom(10)
u1.send mesg, 0, addr[3], addr[1]

p u2.recv(100) #=> "hi"

# File lib/resolv-replace.rb, line 46
def send(mesg, flags, *rest)
  if rest.length == 2
    host, port = rest
    begin
      addrs = Resolv.getaddresses(host)
    rescue Resolv::ResolvError
      raise SocketError, "Hostname not known: #{host}"
    end
    addrs[0...-1].each {|addr|
      begin
        return original_resolv_send(mesg, flags, addr, port)
      rescue SystemCallError
      end
    }
    original_resolv_send(mesg, flags, addrs[-1], port)
  else
    original_resolv_send(mesg, flags, *rest)
  end
end


class UNIXServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class UNIXServer

UNIXServer represents a UNIX domain stream server socket.

In Files

  • ext/socket/unixserver.c

Parent

UNIXSocket

Public Class Methods

new(path) → unixserver click to toggle source

Creates a new UNIX server socket bound to path.

serv = UNIXServer.new("/tmp/sock")
s = serv.accept
p s.read
static VALUE
unix_svr_init(VALUE sock, VALUE path)
{
    return rsock_init_unixsock(sock, path, 1);
}

Public Instance Methods

accept → unixsocket click to toggle source

Accepts a new connection. It returns new UNIXSocket object.

UNIXServer.open("/tmp/sock") {|serv|
  UNIXSocket.open("/tmp/sock") {|c|
    s = serv.accept
    s.puts "hi"
    s.close
    p c.read #=> "hi\n"
  }
}

static VALUE
unix_accept(VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_un from;
    socklen_t fromlen;

    GetOpenFile(sock, fptr);
    fromlen = (socklen_t)sizeof(struct sockaddr_un);
    return rsock_s_accept(rb_cUNIXSocket, fptr->fd,
                          (struct sockaddr*)&from, &fromlen);
}
accept_nonblock → unixsocket click to toggle source

Accepts an incoming connection using accept(2) after O_NONBLOCK is set for the underlying file descriptor. It returns an accepted UNIXSocket for the incoming connection.

Example

require 'socket'
serv = UNIXServer.new("/tmp/sock")
begin # emulate blocking accept
  sock = serv.accept_nonblock
rescue IO::WaitReadable, Errno::EINTR
  IO.select([serv])
  retry
end
# sock is an accepted socket.

Refer to Socket#accept for the exceptions that may be thrown if the call to #accept_nonblock fails.

#accept_nonblock may raise any error corresponding to accept(2) failure, including Errno::EWOULDBLOCK.

If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED or Errno::EPROTO, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.

See

  • #accept

  • Socket#accept

static VALUE
unix_accept_nonblock(VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_un from;
    socklen_t fromlen;

    GetOpenFile(sock, fptr);
    fromlen = (socklen_t)sizeof(from);
    return rsock_s_accept_nonblock(rb_cUNIXSocket, fptr,
                                   (struct sockaddr *)&from, &fromlen);
}
listen( int ) → 0 click to toggle source

Listens for connections, using the specified int as the backlog. A call to listen only applies if the socket is of type SOCK_STREAM or SOCK_SEQPACKET.

Parameter

  • backlog - the maximum length of the queue for pending connections.

Example 1

require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
socket.bind( sockaddr )
socket.listen( 5 )

Example 2 (listening on an arbitrary port, unix-based systems only):

require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
socket.listen( 1 )

Unix-based Exceptions

On unix based systems the above will work because a new sockaddr struct is created on the address ADDR_ANY, for an arbitrary port number as handed off by the kernel. It will not work on Windows, because Windows requires that the socket is bound by calling bind before it can listen.

If the backlog amount exceeds the implementation-dependent maximum queue length, the implementation's maximum queue length will be used.

On unix-based based systems the following system exceptions may be raised if the call to listen fails:

  • Errno::EBADF - the socket argument is not a valid file descriptor

  • Errno::EDESTADDRREQ - the socket is not bound to a local address, and the protocol does not support listening on an unbound socket

  • Errno::EINVAL - the socket is already connected

  • Errno::ENOTSOCK - the socket argument does not refer to a socket

  • Errno::EOPNOTSUPP - the socket protocol does not support listen

  • Errno::EACCES - the calling process does not have appropriate privileges

  • Errno::EINVAL - the socket has been shut down

  • Errno::ENOBUFS - insufficient resources are available in the system to complete the call

Windows Exceptions

On Windows systems the following system exceptions may be raised if the call to listen fails:

  • Errno::ENETDOWN - the network is down

  • Errno::EADDRINUSE - the socket's local address is already in use. This usually occurs during the execution of bind but could be delayed if the call to bind was to a partially wildcard address (involving ADDR_ANY) and if a specific address needs to be committed at the time of the call to listen

  • Errno::EINPROGRESS - a Windows Sockets 1.1 call is in progress or the service provider is still processing a callback function

  • Errno::EINVAL - the socket has not been bound with a call to bind.

  • Errno::EISCONN - the socket is already connected

  • Errno::EMFILE - no more socket descriptors are available

  • Errno::ENOBUFS - no buffer space is available

  • Errno::ENOTSOC - socket is not a socket

  • Errno::EOPNOTSUPP - the referenced socket is not a type that supports the listen method

See

  • listen manual pages on unix-based systems

  • listen function in Microsoft's Winsock functions reference

VALUE
rsock_sock_listen(VALUE sock, VALUE log)
{
    rb_io_t *fptr;
    int backlog;

    rb_secure(4);
    backlog = NUM2INT(log);
    GetOpenFile(sock, fptr);
    if (listen(fptr->fd, backlog) < 0)
    rb_sys_fail("listen(2)");

    return INT2FIX(0);
}
sysaccept → file_descriptor click to toggle source

Accepts a new connection. It returns the new file descriptor which is an integer.

UNIXServer.open("/tmp/sock") {|serv|
  UNIXSocket.open("/tmp/sock") {|c|
    fd = serv.sysaccept
    s = IO.new(fd)
    s.puts "hi"
    s.close
    p c.read #=> "hi\n"
  }
}

static VALUE
unix_sysaccept(VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_un from;
    socklen_t fromlen;

    GetOpenFile(sock, fptr);
    fromlen = (socklen_t)sizeof(struct sockaddr_un);
    return rsock_s_accept(0, fptr->fd, (struct sockaddr*)&from, &fromlen);
}


class UNIXSocket - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class UNIXSocket

UNIXSocket represents a UNIX domain stream client socket.

In Files

  • ext/socket/unixsocket.c

Parent

BasicSocket

Public Class Methods

new(path) → unixsocket click to toggle source

Creates a new UNIX client socket connected to path.

s = UNIXSocket.new("/tmp/sock")
s.send "hello", 0
static VALUE
unix_init(VALUE sock, VALUE path)
{
    return rsock_init_unixsock(sock, path, 0);
}
pair([type [, protocol]]) → [unixsocket1, unixsocket2] click to toggle source
socketpair([type [, protocol]]) → [unixsocket1, unixsocket2]

Creates a pair of sockets connected each other.

socktype should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.

protocol should be a protocol defined in the domain. 0 is default protocol for the domain.

s1, s2 = UNIXSocket.pair
s1.send "a", 0
s1.send "b", 0
p s2.recv(10) #=> "ab"

static VALUE
unix_s_socketpair(int argc, VALUE *argv, VALUE klass)
{
    VALUE domain, type, protocol;
    VALUE args[3];

    domain = INT2FIX(PF_UNIX);
    rb_scan_args(argc, argv, "02", &type, &protocol);
    if (argc == 0)
        type = INT2FIX(SOCK_STREAM);
    if (argc <= 1)
        protocol = INT2FIX(0);

    args[0] = domain;
    args[1] = type;
    args[2] = protocol;

    return rsock_sock_s_socketpair(3, args, klass);
}
pair([type [, protocol]]) → [unixsocket1, unixsocket2] click to toggle source
socketpair([type [, protocol]]) → [unixsocket1, unixsocket2]

Creates a pair of sockets connected each other.

socktype should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.

protocol should be a protocol defined in the domain. 0 is default protocol for the domain.

s1, s2 = UNIXSocket.pair
s1.send "a", 0
s1.send "b", 0
p s2.recv(10) #=> "ab"

static VALUE
unix_s_socketpair(int argc, VALUE *argv, VALUE klass)
{
    VALUE domain, type, protocol;
    VALUE args[3];

    domain = INT2FIX(PF_UNIX);
    rb_scan_args(argc, argv, "02", &type, &protocol);
    if (argc == 0)
        type = INT2FIX(SOCK_STREAM);
    if (argc <= 1)
        protocol = INT2FIX(0);

    args[0] = domain;
    args[1] = type;
    args[2] = protocol;

    return rsock_sock_s_socketpair(3, args, klass);
}

Public Instance Methods

addr → [address_family, unix_path] click to toggle source

Returns the local address as an array which contains address_family and unix_path.

Example

serv = UNIXServer.new("/tmp/sock")
p serv.addr #=> ["AF_UNIX", "/tmp/sock"]

static VALUE
unix_addr(VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_un addr;
    socklen_t len = (socklen_t)sizeof addr;
    socklen_t len0 = len;

    GetOpenFile(sock, fptr);

    if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
        rb_sys_fail("getsockname(2)");
    if (len0 < len) len = len0;
    return rsock_unixaddr(&addr, len);
}
path → path click to toggle source

Returns the path of the local address of unixsocket.

s = UNIXServer.new("/tmp/sock")
p s.path #=> "/tmp/sock"

static VALUE
unix_path(VALUE sock)
{
    rb_io_t *fptr;

    GetOpenFile(sock, fptr);
    if (NIL_P(fptr->pathv)) {
        struct sockaddr_un addr;
        socklen_t len = (socklen_t)sizeof(addr);
        socklen_t len0 = len;
        if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
            rb_sys_fail(0);
        if (len0 < len) len = len0;
        fptr->pathv = rb_obj_freeze(rsock_unixpath_str(&addr, len));
    }
    return rb_str_dup(fptr->pathv);
}
peeraddr → [address_family, unix_path] click to toggle source

Returns the remote address as an array which contains address_family and unix_path.

Example

serv = UNIXServer.new("/tmp/sock")
c = UNIXSocket.new("/tmp/sock")
p c.peeraddr #=> ["AF_UNIX", "/tmp/sock"]

static VALUE
unix_peeraddr(VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_un addr;
    socklen_t len = (socklen_t)sizeof addr;
    socklen_t len0 = len;

    GetOpenFile(sock, fptr);

    if (getpeername(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
        rb_sys_fail("getpeername(2)");
    if (len0 < len) len = len0;
    return rsock_unixaddr(&addr, len);
}
recv_io([klass [, mode]]) → io click to toggle source

UNIXServer.open(“/tmp/sock”) {|serv|

UNIXSocket.open("/tmp/sock") {|c|
  s = serv.accept

  c.send_io STDOUT
  stdout = s.recv_io

  p STDOUT.fileno #=> 1
  p stdout.fileno #=> 7

  stdout.puts "hello" # outputs "hello\n" to standard output.
}

}

static VALUE
unix_recv_io(int argc, VALUE *argv, VALUE sock)
{
    VALUE klass, mode;
    rb_io_t *fptr;
    struct iomsg_arg arg;
    struct iovec vec[2];
    char buf[1];

    int fd;
#if FD_PASSING_BY_MSG_CONTROL
    struct {
        struct cmsghdr hdr;
        char pad[8+sizeof(int)+8];
    } cmsg;
#endif

    rb_scan_args(argc, argv, "02", &klass, &mode);
    if (argc == 0)
        klass = rb_cIO;
    if (argc <= 1)
        mode = Qnil;

    GetOpenFile(sock, fptr);

    arg.msg.msg_name = NULL;
    arg.msg.msg_namelen = 0;

    vec[0].iov_base = buf;
    vec[0].iov_len = sizeof(buf);
    arg.msg.msg_iov = vec;
    arg.msg.msg_iovlen = 1;

#if FD_PASSING_BY_MSG_CONTROL
    arg.msg.msg_control = (caddr_t)&cmsg;
    arg.msg.msg_controllen = (socklen_t)CMSG_SPACE(sizeof(int));
    arg.msg.msg_flags = 0;
    cmsg.hdr.cmsg_len = (socklen_t)CMSG_LEN(sizeof(int));
    cmsg.hdr.cmsg_level = SOL_SOCKET;
    cmsg.hdr.cmsg_type = SCM_RIGHTS;
    fd = -1;
    memcpy(CMSG_DATA(&cmsg.hdr), &fd, sizeof(int));
#else
    arg.msg.msg_accrights = (caddr_t)&fd;
    arg.msg.msg_accrightslen = sizeof(fd);
    fd = -1;
#endif

    arg.fd = fptr->fd;
    while ((int)BLOCKING_REGION_FD(recvmsg_blocking, &arg) == -1) {
        if (!rb_io_wait_readable(arg.fd))
            rb_sys_fail("recvmsg(2)");
    }

#if FD_PASSING_BY_MSG_CONTROL
    if (arg.msg.msg_controllen < (socklen_t)sizeof(struct cmsghdr)) {
        rb_raise(rb_eSocket,
                 "file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)",
                 (int)arg.msg.msg_controllen, (int)sizeof(struct cmsghdr));
    }
    if (cmsg.hdr.cmsg_level != SOL_SOCKET) {
        rb_raise(rb_eSocket,
                 "file descriptor was not passed (cmsg_level=%d, %d expected)",
                 cmsg.hdr.cmsg_level, SOL_SOCKET);
    }
    if (cmsg.hdr.cmsg_type != SCM_RIGHTS) {
        rb_raise(rb_eSocket,
                 "file descriptor was not passed (cmsg_type=%d, %d expected)",
                 cmsg.hdr.cmsg_type, SCM_RIGHTS);
    }
    if (arg.msg.msg_controllen < (socklen_t)CMSG_LEN(sizeof(int))) {
        rb_raise(rb_eSocket,
                 "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)",
                 (int)arg.msg.msg_controllen, (int)CMSG_LEN(sizeof(int)));
    }
    if ((socklen_t)CMSG_SPACE(sizeof(int)) < arg.msg.msg_controllen) {
        rb_raise(rb_eSocket,
                 "file descriptor was not passed (msg_controllen=%d bigger than CMSG_SPACE(sizeof(int))=%d)",
                 (int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int)));
    }
    if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {
        rsock_discard_cmsg_resource(&arg.msg, 0);
        rb_raise(rb_eSocket,
                 "file descriptor was not passed (cmsg_len=%d, %d expected)",
                 (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int)));
    }
#else
    if (arg.msg.msg_accrightslen != sizeof(fd)) {
        rb_raise(rb_eSocket,
                 "file descriptor was not passed (accrightslen) : %d != %d",
                 arg.msg.msg_accrightslen, (int)sizeof(fd));
    }
#endif

#if FD_PASSING_BY_MSG_CONTROL
    memcpy(&fd, CMSG_DATA(&cmsg.hdr), sizeof(int));
#endif
    rb_fd_fix_cloexec(fd);

    if (klass == Qnil)
        return INT2FIX(fd);
    else {
        ID for_fd;
        int ff_argc;
        VALUE ff_argv[2];
        CONST_ID(for_fd, "for_fd");
        ff_argc = mode == Qnil ? 1 : 2;
        ff_argv[0] = INT2FIX(fd);
        ff_argv[1] = mode;
        return rb_funcall2(klass, for_fd, ff_argc, ff_argv);
    }
}
recvfrom(maxlen [, flags]) → [mesg, unixaddress] click to toggle source

Receives a message via unixsocket.

maxlen is the maximum number of bytes to receive.

flags should be a bitwise OR of Socket::MSG_* constants.

s1 = Socket.new(:UNIX, :DGRAM, 0)
s1_ai = Addrinfo.unix("/tmp/sock1")
s1.bind(s1_ai)

s2 = Socket.new(:UNIX, :DGRAM, 0)
s2_ai = Addrinfo.unix("/tmp/sock2")
s2.bind(s2_ai)
s3 = UNIXSocket.for_fd(s2.fileno)

s1.send "a", 0, s2_ai
p s3.recvfrom(10) #=> ["a", ["AF_UNIX", "/tmp/sock1"]]

static VALUE
unix_recvfrom(int argc, VALUE *argv, VALUE sock)
{
    return rsock_s_recvfrom(sock, argc, argv, RECV_UNIX);
}
send_io(io) → nil click to toggle source

Sends io as file descriptor passing.

s1, s2 = UNIXSocket.pair

s1.send_io STDOUT
stdout = s2.recv_io

p STDOUT.fileno #=> 1
p stdout.fileno #=> 6

stdout.puts "hello" # outputs "hello\n" to standard output.

static VALUE
unix_send_io(VALUE sock, VALUE val)
{
    int fd;
    rb_io_t *fptr;
    struct iomsg_arg arg;
    struct iovec vec[1];
    char buf[1];

#if FD_PASSING_BY_MSG_CONTROL
    struct {
        struct cmsghdr hdr;
        char pad[8+sizeof(int)+8];
    } cmsg;
#endif

    if (rb_obj_is_kind_of(val, rb_cIO)) {
        rb_io_t *valfptr;
        GetOpenFile(val, valfptr);
        fd = valfptr->fd;
    }
    else if (FIXNUM_P(val)) {
        fd = FIX2INT(val);
    }
    else {
        rb_raise(rb_eTypeError, "neither IO nor file descriptor");
    }

    GetOpenFile(sock, fptr);

    arg.msg.msg_name = NULL;
    arg.msg.msg_namelen = 0;

    /* Linux and Solaris doesn't work if msg_iov is NULL. */
    buf[0] = '\0';
    vec[0].iov_base = buf;
    vec[0].iov_len = 1;
    arg.msg.msg_iov = vec;
    arg.msg.msg_iovlen = 1;

#if FD_PASSING_BY_MSG_CONTROL
    arg.msg.msg_control = (caddr_t)&cmsg;
    arg.msg.msg_controllen = (socklen_t)CMSG_LEN(sizeof(int));
    arg.msg.msg_flags = 0;
    MEMZERO((char*)&cmsg, char, sizeof(cmsg));
    cmsg.hdr.cmsg_len = (socklen_t)CMSG_LEN(sizeof(int));
    cmsg.hdr.cmsg_level = SOL_SOCKET;
    cmsg.hdr.cmsg_type = SCM_RIGHTS;
    memcpy(CMSG_DATA(&cmsg.hdr), &fd, sizeof(int));
#else
    arg.msg.msg_accrights = (caddr_t)&fd;
    arg.msg.msg_accrightslen = sizeof(fd);
#endif

    arg.fd = fptr->fd;
    while ((int)BLOCKING_REGION_FD(sendmsg_blocking, &arg) == -1) {
        if (!rb_io_wait_writable(arg.fd))
            rb_sys_fail("sendmsg(2)");
    }

    return Qnil;
}


module URI - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module URI

URI is a module providing classes to handle Uniform Resource Identifiers (RFC2396)

Features

  • Uniform handling of handling URIs

  • Flexibility to introduce custom URI schemes

  • Flexibility to have an alternate URI::Parser (or just different patterns and regexp's)

Basic example

require 'uri'

uri = URI("http://foo.com/posts?id=30&limit=5#time=1305298413")
#=> #<URI::HTTP:0x00000000b14880
      URL:http://foo.com/posts?id=30&limit=5#time=1305298413>
uri.scheme
#=> "http"
uri.host
#=> "foo.com"
uri.path
#=> "/posts"
uri.query
#=> "id=30&limit=5"
uri.fragment
#=> "time=1305298413"

uri.to_s
#=> "http://foo.com/posts?id=30&limit=5#time=1305298413"

Adding custom URIs

module URI
  class RSYNC < Generic
    DEFAULT_PORT = 873
  end
  @@schemes['RSYNC'] = RSYNC
end
#=> URI::RSYNC

URI.scheme_list
#=> {"FTP"=>URI::FTP, "HTTP"=>URI::HTTP, "HTTPS"=>URI::HTTPS,
     "LDAP"=>URI::LDAP, "LDAPS"=>URI::LDAPS, "MAILTO"=>URI::MailTo,
     "RSYNC"=>URI::RSYNC}

uri = URI("rsync://rsync.foo.com")
#=> #<URI::RSYNC:0x00000000f648c8 URL:rsync://rsync.foo.com>

RFC References

A good place to view an RFC spec is www.ietf.org/rfc.html

Here is a list of all related RFC's.

  • RFC822

  • RFC1738

  • RFC2255

  • RFC2368

  • RFC2373

  • RFC2396

  • RFC2732

  • RFC3986

Class tree

  • URI::Generic (in uri/generic.rb)

    • URI::FTP - (in uri/ftp.rb)

    • URI::HTTP - (in uri/http.rb)

      • URI::HTTPS - (in uri/https.rb)

    • URI::LDAP - (in uri/ldap.rb)

      • URI::LDAPS - (in uri/ldaps.rb)

    • URI::MailTo - (in uri/mailto.rb)

  • URI::Parser - (in uri/common.rb)

  • URI::REGEXP - (in uri/common.rb)

    • URI::REGEXP::PATTERN - (in uri/common.rb)

  • URI::Util - (in uri/common.rb)

  • URI::Escape - (in uri/common.rb)

  • URI::Error - (in uri/common.rb)

    • URI::InvalidURIError - (in uri/common.rb)

    • URI::InvalidComponentError - (in uri/common.rb)

    • URI::BadURIError - (in uri/common.rb)

Copyright Info

Author

Akira Yamada <akira@ruby-lang.org>

Documentation

Akira Yamada <akira@ruby-lang.org> Dmitry V. Sabanin <sdmitry@lrn.ru> Vincent Batts <vbatts@hashbangbash.com>

License

Copyright © 2001 akira yamada <akira@ruby-lang.org> You can redistribute it and/or modify it under the same term as Ruby.

Revision

$Id: uri.rb 31555 2011-05-13 20:03:21Z drbrain $

In Files

  • lib/open-uri.rb
  • lib/uri/common.rb
  • lib/uri/ftp.rb
  • lib/uri/generic.rb
  • lib/uri/http.rb
  • lib/uri/https.rb
  • lib/uri/ldap.rb
  • lib/uri/ldaps.rb
  • lib/uri/mailto.rb
  • lib/uri.rb

Included Modules

  • URI::REGEXP

Constants

DEFAULT_PARSER

URI::Parser.new

Public Class Methods

decode_www_form(str, enc=Encoding::UTF_8) click to toggle source

Decode URL-encoded form data from given str.

This decodes application/x-www-form-urlencoded data and returns array of key-value array. This internally uses ::decode_www_form_component.

charset hack is not supported now because the mapping from given charset to Ruby's encoding is not clear yet. see also www.w3.org/TR/html5/syntax.html#character-encodings-0

This refers www.w3.org/TR/html5/forms.html#url-encoded-form-data

ary = ::decode_www_form(“a=1&a=2&b=3”)
p ary                  #=> [['a', '1'], ['a',
'2'], ['b', '3']] p ary.assoc('a').last
#=> '1' p ary.assoc('b').last  #=> '3' p
ary.rassoc('a').last #=> '2' p Hash            # => {“a”=>“2”, “b”=>“3”}

See ::decode_www_form_component, ::encode_www_form

# File lib/uri/common.rb, line 974
def self.decode_www_form(str, enc=Encoding::UTF_8)
  return [] if str.empty?
  unless /\A#{WFKV_}=#{WFKV_}(?:[;&]#{WFKV_}=#{WFKV_})*\z/ =~ str
    raise ArgumentError, "invalid data of application/x-www-form-urlencoded (#{str})"
  end
  ary = []
  $&.scan(/([^=;&]+)=([^;&]*)/) do
    ary << [decode_www_form_component($1, enc), decode_www_form_component($2, enc)]
  end
  ary
end
decode_www_form_component(str, enc=Encoding::UTF_8) click to toggle source

Decode given str of URL-encoded form data.

This decodes + to SP.

See ::encode_www_form_component, ::decode_www_form

# File lib/uri/common.rb, line 897
def self.decode_www_form_component(str, enc=Encoding::UTF_8)
  raise ArgumentError, "invalid %-encoding (#{str})" unless /\A[^%]*(?:%\h\h[^%]*)*\z/ =~ str
  str.dup.force_encoding("ASCII-8BIT")         .gsub(/\+|%\h\h/, TBLDECWWWCOMP_)         .force_encoding(enc)
end
encode_www_form(enum) click to toggle source

Generate URL-encoded form data from given enum.

This generates application/x-www-form-urlencoded data defined in HTML5 from given an Enumerable object.

This internally uses ::encode_www_form_component.

This method doesn't convert the encoding of given items, so convert them before call this method if you want to send data as other than original encoding or mixed encoding data. (Strings which are encoded in an HTML5 ASCII incompatible encoding are converted to UTF-8.)

This method doesn't handle files. When you send a file, use multipart/form-data.

This is an implementation of www.w3.org/TR/html5/forms.html#url-encoded-form-data

URI.encode_www_form([["q", "ruby"], ["lang", "en"]])
#=> "q=ruby&lang=en"
URI.encode_www_form("q" => "ruby", "lang" => "en")
#=> "q=ruby&lang=en"
URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en")
#=> "q=ruby&q=perl&lang=en"
URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
#=> "q=ruby&q=perl&lang=en"

See ::encode_www_form_component, ::decode_www_form

# File lib/uri/common.rb, line 932
def self.encode_www_form(enum)
  enum.map do |k,v|
    if v.nil?
      encode_www_form_component(k)
    elsif v.respond_to?(:to_ary)
      v.to_ary.map do |w|
        str = encode_www_form_component(k)
        unless w.nil?
          str << '='
          str << encode_www_form_component(w)
        end
      end.join('&')
    else
      str = encode_www_form_component(k)
      str << '='
      str << encode_www_form_component(v)
    end
  end.join('&')
end
encode_www_form_component(str) click to toggle source

Encode given str to URL-encoded form data.

This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP (ASCII space) to + and converts others to %XX.

This is an implementation of www.w3.org/TR/html5/association-of-controls-and-forms.html#url-encoded-form-data

See ::decode_www_form_component, ::encode_www_form

# File lib/uri/common.rb, line 880
def self.encode_www_form_component(str)
  str = str.to_s
  if HTML5ASCIIINCOMPAT.include?(str.encoding)
    str = str.encode(Encoding::UTF_8)
  else
    str = str.dup
  end
  str.force_encoding(Encoding::ASCII_8BIT)
  str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_)
  str.force_encoding(Encoding::US_ASCII)
end
extract(str, schemes = nil, &block) click to toggle source

Synopsis

URI::extract(str[, schemes][,&blk])

Args

str

String to extract URIs from.

schemes

Limit URI matching to a specific schemes.

Description

Extracts URIs from a string. If block given, iterates through all matched URIs. Returns nil if block given or array with matches.

Usage

require "uri"

URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
# => ["http://foo.example.com/bla", "mailto:test@example.com"]

# File lib/uri/common.rb, line 812
def self.extract(str, schemes = nil, &block)
  DEFAULT_PARSER.extract(str, schemes, &block)
end
join(*str) click to toggle source

Synopsis

URI::join(str[, str, ...])

Args

str

String(s) to work with

Description

Joins URIs.

Usage

require 'uri'

p URI.join("http://example.com/","main.rbx")
# => #<URI::HTTP:0x2022ac02 URL:http://localhost/main.rbx>

p URI.join('http://example.com', 'foo')
# => #<URI::HTTP:0x01ab80a0 URL:http://example.com/foo>

p URI.join('http://example.com', '/foo', '/bar')
# => #<URI::HTTP:0x01aaf0b0 URL:http://example.com/bar>

p URI.join('http://example.com', '/foo', 'bar')
# => #<URI::HTTP:0x801a92af0 URL:http://example.com/bar>

p URI.join('http://example.com', '/foo/', 'bar')
# => #<URI::HTTP:0x80135a3a0 URL:http://example.com/foo/bar>

# File lib/uri/common.rb, line 784
def self.join(*str)
  DEFAULT_PARSER.join(*str)
end
parse(uri) click to toggle source

Synopsis

URI::parse(uri_str)

Args

uri_str

String with URI.

Description

Creates one of the URI's subclasses instance from the string.

Raises

URI::InvalidURIError

Raised if URI given is not a correct one.

Usage

require 'uri'

uri = URI.parse("http://www.ruby-lang.org/")
p uri
# => #<URI::HTTP:0x202281be URL:http://www.ruby-lang.org/>
p uri.scheme
# => "http"
p uri.host
# => "www.ruby-lang.org"

# File lib/uri/common.rb, line 746
def self.parse(uri)
  DEFAULT_PARSER.parse(uri)
end
regexp(schemes = nil) click to toggle source

Synopsis

URI::regexp([match_schemes])

Args

match_schemes

Array of schemes. If given, resulting regexp matches to URIs whose scheme is one of the match_schemes.

Description

Returns a Regexp object which matches to URI-like strings. The Regexp object returned by this method includes arbitrary number of capture group (parentheses). Never rely on it's number.

Usage

require 'uri'

# extract first URI from html_string
html_string.slice(URI.regexp)

# remove ftp URIs
html_string.sub(URI.regexp(['ftp'])

# You should not rely on the number of parentheses
html_string.scan(URI.regexp) do |*matches|
  p $&
end

# File lib/uri/common.rb, line 847
def self.regexp(schemes = nil)
  DEFAULT_PARSER.make_regexp(schemes)
end
scheme_list() click to toggle source

Returns a Hash of the defined schemes

# File lib/uri/common.rb, line 659
def self.scheme_list
  @@schemes
end
split(uri) click to toggle source

Synopsis

URI::split(uri)

Args

uri

String with URI.

Description

Splits the string on following parts and returns array with result:

* Scheme
* Userinfo
* Host
* Port
* Registry
* Path
* Opaque
* Query
* Fragment

Usage

require 'uri'

p URI.split("http://www.ruby-lang.org/")
# => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil]

# File lib/uri/common.rb, line 711
def self.split(uri)
  DEFAULT_PARSER.split(uri)
end


class URI::BadURIError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::BadURIError

URI is valid, bad usage is not.

In Files

  • lib/uri/common.rb

Parent

URI::Error


class URI::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::Error

Base class for all URI exceptions.

In Files

  • lib/uri/common.rb

Parent

StandardError


module URI::Escape - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module URI::Escape

module for escaping unsafe characters with codes.

In Files

  • lib/uri/common.rb

Public Instance Methods

decode(*arg) click to toggle source
Alias for: unescape
encode(*arg) click to toggle source
Alias for: escape
escape(*arg) click to toggle source

Synopsis

URI.escape(str [, unsafe])

Args

str

String to replaces in.

unsafe

Regexp that matches all symbols that must be replaced with codes. By default uses REGEXP::UNSAFE. When this argument is a String, it represents a character set.

Description

Escapes the string, replacing all unsafe characters with codes.

Usage

require 'uri'

enc_uri = URI.escape("http://example.com/?a=\111\\115"")
p enc_uri
# => "http://example.com/?a=%09%0D"

p URI.unescape(enc_uri)
# => "http://example.com/?a=\t\r"

p URI.escape("@?@!", "!?")
# => "@%3F@%21"

# File lib/uri/common.rb, line 621
def escape(*arg)
  warn "#{caller(1)[0]}: warning: URI.escape is obsolete" if $VERBOSE
  DEFAULT_PARSER.escape(*arg)
end
Also aliased as: encode
unescape(*arg) click to toggle source

Synopsis

URI.unescape(str)

Args

str

Unescapes the string.

Usage

require 'uri'

enc_uri = URI.escape("http://example.com/?a=\111\\115"")
p enc_uri
# => "http://example.com/?a=%09%0D"

p URI.unescape(enc_uri)
# => "http://example.com/?a=\t\r"

# File lib/uri/common.rb, line 647
def unescape(*arg)
  warn "#{caller(1)[0]}: warning: URI.unescape is obsolete" if $VERBOSE
  DEFAULT_PARSER.unescape(*arg)
end
Also aliased as: decode


class URI::FTP - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::FTP

FTP URI syntax is defined by RFC1738 section 3.2.

This class will be redesigned because of difference of implementations; the structure of its path. draft-hoffman-ftp-uri-04 is a draft but it is a good summary about the de facto spec. tools.ietf.org/html/draft-hoffman-ftp-uri-04

In Files

  • lib/open-uri.rb
  • lib/uri/ftp.rb

Parent

Generic

Included Modules

  • OpenURI::OpenRead

Constants

COMPONENT

An Array of the available components for URI::FTP

DEFAULT_PORT

A Default port of 21 for URI::FTP

TYPECODE

Typecode is “a”, “i” or “d”.

  • “a” indicates a text file (the FTP command was ASCII)

  • “i” indicates a binary file (FTP command IMAGE)

  • “d” indicates the contents of a directory should be displayed

TYPECODE_PREFIX

Typecode prefix

';type='

Attributes

typecode[R]

typecode accessor

see URI::FTP::COMPONENT

Public Class Methods

build(args) click to toggle source

Description

Creates a new URI::FTP object from components, with syntax checking.

The components accepted are userinfo, host, port, path and typecode.

The components should be provided either as an Array, or as a Hash with keys formed by preceding the component names with a colon.

If an Array is used, the components must be passed in the order

userinfo, host, port, path, typecode

If the path supplied is absolute, it will be escaped in order to make it absolute in the URI. Examples:

require 'uri'

uri = URI::FTP.build(['user:password', 'ftp.example.com', nil,
  '/path/file.> zip', 'i'])
puts uri.to_s  ->  ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=a

uri2 = URI::FTP.build({:host => 'ftp.example.com',
  :path => 'ruby/src'})
puts uri2.to_s  ->  ftp://ftp.example.com/ruby/src

# File lib/uri/ftp.rb, line 95
def self.build(args)

  # Fix the incoming path to be generic URL syntax
  # FTP path  ->  URL path
  # foo/bar       /foo/bar
  # /foo/bar      /%2Ffoo/bar
  #
  if args.kind_of?(Array)
    args[3] = '/' + args[3].sub(/^\//, '%2F')
  else
    args[:path] = '/' + args[:path].sub(/^\//, '%2F')
  end

  tmp = Util::make_components_hash(self, args)

  if tmp[:typecode]
    if tmp[:typecode].size == 1
      tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode]
    end
    tmp[:path] << tmp[:typecode]
  end

  return super(tmp)
end
new(*arg) click to toggle source

Description

Creates a new URI::FTP object from generic URL components with no syntax checking.

Unlike build(), this method does not escape the path component as required by RFC1738; instead it is treated as per RFC2396.

Arguments are scheme, userinfo, host, port, registry, path, opaque, query and fragment, in that order.

# File lib/uri/ftp.rb, line 132
def initialize(*arg)
  raise InvalidURIError unless arg[5]
  arg[5] = arg[5].sub(/^\//,'').sub(/^%2F/,'/')
  super(*arg)
  @typecode = nil
  tmp = @path.index(TYPECODE_PREFIX)
  if tmp
    typecode = @path[tmp + TYPECODE_PREFIX.size..-1]
    @path = @path[0..tmp - 1]

    if arg[-1]
      self.typecode = typecode
    else
      self.set_typecode(typecode)
    end
  end
end

Public Instance Methods

path() click to toggle source

Returns the path from an FTP URI.

RFC 1738 specifically states that the path for an FTP URI does not include the / which separates the URI path from the URI host. Example:

ftp://ftp.example.com/pub/ruby

The above URI indicates that the client should connect to ftp.example.com then cd pub/ruby from the initial login directory.

If you want to cd to an absolute directory, you must include an escaped / (%2F) in the path. Example:

ftp://ftp.example.com/%2Fpub/ruby

This method will then return “/pub/ruby”

# File lib/uri/ftp.rb, line 233
def path
  return @path.sub(/^\//,'').sub(/^%2F/,'/')
end
to_s() click to toggle source
# File lib/uri/ftp.rb, line 242
def to_s
  save_path = nil
  if @typecode
    save_path = @path
    @path = @path + TYPECODE_PREFIX + @typecode
  end
  str = super
  if @typecode
    @path = save_path
  end

  return str
end
typecode=(typecode) click to toggle source

Args

v

String

Description

public setter for the typecode v. (with validation)

see also URI::FTP.check_typecode

Usage

require 'uri'

uri = URI.parse("ftp://john@ftp.example.com/my_file.img")
#=> #<URI::FTP:0x00000000923650 URL:ftp://john@ftp.example.com/my_file.img>
uri.typecode = "i"
# =>  "i"
uri
#=> #<URI::FTP:0x00000000923650 URL:ftp://john@ftp.example.com/my_file.img;type=i>

# File lib/uri/ftp.rb, line 201
def typecode=(typecode)
  check_typecode(typecode)
  set_typecode(typecode)
  typecode
end

Protected Instance Methods

set_path(v) click to toggle source
# File lib/uri/ftp.rb, line 237
def set_path(v)
  super("/" + v.sub(/^\//, "%2F"))
end
set_typecode(v) click to toggle source

private setter for the typecode v

see also #typecode=

# File lib/uri/ftp.rb, line 172
def set_typecode(v)
  @typecode = v
end


class URI::Generic - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::Generic

Base class for all URI classes. Implements generic URI syntax as per RFC 2396.

In Files

  • lib/uri/generic.rb

Parent

Object

Included Modules

  • URI

Constants

COMPONENT

An Array of the available components for URI::Generic

DEFAULT_PORT

A Default port of nil for URI::Generic

USE_REGISTRY

Default to not use the registry for a URI::Generic

Attributes

fragment[R]

returns the fragment component of the URI.

URI("http://foo/bar/baz?search=FooBar#ponies").fragment #=> "ponies"
host[R]

returns the host component of the URI.

URI("http://foo/bar/baz").host #=> "foo"

It returns nil if no host component.

URI("mailto:foo@example.org").host #=> nil

The component doesn't contains the port number.

URI("http://foo:8080/bar/baz").host #=> "foo"

Since IPv6 addresses are wrapped by brackets in URIs, this method returns IPv6 addresses wrapped by brackets. This form is not appropriate to pass socket methods such as TCPSocket.open. If unwrapped host names are required, use “hostname” method.

URI("http://[::1]/bar/baz").host #=> "[::1]"
URI("http://[::1]/bar/baz").hostname #=> "::1"
opaque[R]

returns the opaque part of the URI.

URI("mailto:foo@example.org").opaque #=> "foo@example.org"

Portion of the path that does make use of the slash '/'. The path typically refers to the absolute path and the opaque part.

(see RFC2396 Section 3 and 5.2)
path[R]

returns the path component of the URI.

URI("http://foo/bar/baz").path #=> "/bar/baz"
port[R]

returns the port component of the URI.

URI("http://foo/bar/baz").port #=> "80"

URI("http://foo:8080/bar/baz").port #=> "8080"
query[R]

returns the query component of the URI.

URI("http://foo/bar/baz?search=FooBar").query #=> "search=FooBar"
registry[R]

returns the registry component of the URI.

(see RFC2396 Section 3.2)
scheme[R]

returns the scheme component of the URI.

URI("http://foo/bar/baz").scheme #=> "http"

Public Class Methods

build(args) click to toggle source

Synopsis

See new

Description

Creates a new URI::Generic instance from components of URI::Generic with check. Components are: scheme, userinfo, host, port, registry, path, opaque, query and fragment. You can provide arguments either by an Array or a Hash. See new for hash keys to use or for order of array items.

# File lib/uri/generic.rb, line 121
def self.build(args)
  if args.kind_of?(Array) &&
      args.size == ::URI::Generic::COMPONENT.size
    tmp = args.dup
  elsif args.kind_of?(Hash)
    tmp = ::URI::Generic::COMPONENT.collect do |c|
      if args.include?(c)
        args[c]
      else
        nil
      end
    end
  else
    component = self.class.component rescue ::URI::Generic::COMPONENT
    raise ArgumentError,
    "expected Array of or Hash of components of #{self.class} (#{component.join(', ')})"
  end

  tmp << nil
  tmp << true
  return self.new(*tmp)
end
build2(args) click to toggle source

Synopsis

See new

Description

At first, tries to create a new URI::Generic instance using ::build. But, if exception URI::InvalidComponentError is raised, then it URI::Escape#escape all URI components and tries again.

# File lib/uri/generic.rb, line 83
def self.build2(args)
  begin
    return self.build(args)
  rescue InvalidComponentError
    if args.kind_of?(Array)
      return self.build(args.collect{|x|
        if x.is_a?(String)
          DEFAULT_PARSER.escape(x)
        else
          x
        end
      })
    elsif args.kind_of?(Hash)
      tmp = {}
      args.each do |key, value|
        tmp[key] = if value
            DEFAULT_PARSER.escape(value)
          else
            value
          end
      end
      return self.build(tmp)
    end
  end
end
component() click to toggle source

Components of the URI in the order.

# File lib/uri/generic.rb, line 54
def self.component
  self::COMPONENT
end
default_port() click to toggle source

Returns default port

# File lib/uri/generic.rb, line 29
def self.default_port
  self::DEFAULT_PORT
end
new(scheme, userinfo, host, port, registry, path, opaque, query, fragment, parser = DEFAULT_PARSER, arg_check = false) click to toggle source

Args

scheme

Protocol scheme, i.e. 'http','ftp','mailto' and so on.

userinfo

User name and password, i.e. 'sdmitry:bla'

host

Server host name

port

Server port

registry

Registry of naming authorities.

path

Path on server

opaque

Opaque part

query

Query data

fragment

A part of URI after '#' sign

parser

Parser for internal use [URI::DEFAULT_PARSER by default]

arg_check

Check arguments [false by default]

Description

Creates a new URI::Generic instance from “generic'' components without check.

# File lib/uri/generic.rb, line 173
def initialize(scheme,
               userinfo, host, port, registry,
               path, opaque,
               query,
               fragment,
               parser = DEFAULT_PARSER,
               arg_check = false)
  @scheme = nil
  @user = nil
  @password = nil
  @host = nil
  @port = nil
  @path = nil
  @query = nil
  @opaque = nil
  @registry = nil
  @fragment = nil
  @parser = parser == DEFAULT_PARSER ? nil : parser

  if arg_check
    self.scheme = scheme
    self.userinfo = userinfo
    self.host = host
    self.port = port
    self.path = path
    self.query = query
    self.opaque = opaque
    self.registry = registry
    self.fragment = fragment
  else
    self.set_scheme(scheme)
    self.set_userinfo(userinfo)
    self.set_host(host)
    self.set_port(port)
    self.set_path(path)
    self.set_query(query)
    self.set_opaque(opaque)
    self.set_registry(registry)
    self.set_fragment(fragment)
  end
  if @registry && !self.class.use_registry
    raise InvalidURIError,
      "the scheme #{@scheme} does not accept registry part: #{@registry} (or bad hostname?)"
  end

  @scheme.freeze if @scheme
  self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)
  self.set_port(self.default_port) if self.default_port && !@port
end
use_registry() click to toggle source

Returns whether a registry of naming authorities are being used.

# File lib/uri/generic.rb, line 67
def self.use_registry
  self::USE_REGISTRY
end

Public Instance Methods

+(oth) click to toggle source
Alias for: merge
-(oth) click to toggle source
Alias for: route_from
==(oth) click to toggle source

Compares to URI's

# File lib/uri/generic.rb, line 1498
def ==(oth)
  if self.class == oth.class
    self.normalize.component_ary == oth.normalize.component_ary
  else
    false
  end
end
absolute() click to toggle source
Alias for: absolute?
absolute?() click to toggle source

Checks if URI is an absolute one

# File lib/uri/generic.rb, line 1061
def absolute?
  if @scheme
    true
  else
    false
  end
end
Also aliased as: absolute
coerce(oth) click to toggle source

Args

v

URI or String

Description

attempt to parse other URI +oth+
return [parsed_oth, self]

Usage

require 'uri'

uri = URI.parse("http://my.example.com")
uri.coerce("http://foo.com")
#=> [#<URI::HTTP:0x00000000bcb028 URL:http://foo.com/>, #<URI::HTTP:0x00000000d92178 URL:http://my.example.com>]

# File lib/uri/generic.rb, line 1589
def coerce(oth)
  case oth
  when String
    oth = parser.parse(oth)
  else
    super
  end

  return oth, self
end
component() click to toggle source

Components of the URI in the order.

# File lib/uri/generic.rb, line 321
def component
  self.class.component
end
default_port() click to toggle source

Returns default port

# File lib/uri/generic.rb, line 36
def default_port
  self.class.default_port
end
eql?(oth) click to toggle source
# File lib/uri/generic.rb, line 1510
def eql?(oth)
  self.class == oth.class &&
  parser == oth.parser &&
  self.component_ary.eql?(oth.component_ary)
end
find_proxy() click to toggle source

returns a proxy URI. The proxy URI is obtained from environment variables such as http_proxy, ftp_proxy, no_proxy, etc. If there is no proper proxy, nil is returned.

Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.) are examined too.

But http_proxy and HTTP_PROXY is treated specially under CGI environment. It's because HTTP_PROXY may be set by Proxy: header. So HTTP_PROXY is not used. http_proxy is not used too if the variable is case insensitive. CGI_HTTP_PROXY can be used instead.

# File lib/uri/generic.rb, line 1613
def find_proxy
  raise BadURIError, "relative URI: #{self}" if self.relative?
  name = self.scheme.downcase + '_proxy'
  proxy_uri = nil
  if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?
    # HTTP_PROXY conflicts with *_proxy for proxy settings and
    # HTTP_* for header information in CGI.
    # So it should be careful to use it.
    pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/ !~ k }
    case pairs.length
    when 0 # no proxy setting anyway.
      proxy_uri = nil
    when 1
      k, _ = pairs.shift
      if k == 'http_proxy' && ENV[k.upcase] == nil
        # http_proxy is safe to use because ENV is case sensitive.
        proxy_uri = ENV[name]
      else
        proxy_uri = nil
      end
    else # http_proxy is safe to use because ENV is case sensitive.
      proxy_uri = ENV.to_hash[name]
    end
    if !proxy_uri
      # Use CGI_HTTP_PROXY.  cf. libwww-perl.
      proxy_uri = ENV["CGI_#{name.upcase}"]
    end
  elsif name == 'http_proxy'
    unless proxy_uri = ENV[name]
      if proxy_uri = ENV[name.upcase]
        warn 'The environment variable HTTP_PROXY is discouraged.  Use http_proxy.'
      end
    end
  else
    proxy_uri = ENV[name] || ENV[name.upcase]
  end

  if proxy_uri.nil? || proxy_uri.empty?
    return nil
  end

  if self.hostname
    require 'socket'
    begin
      addr = IPSocket.getaddress(self.hostname)
      return nil if /\A127\.|\A::1\z/ =~ addr
    rescue SocketError
    end
  end

  name = 'no_proxy'
  if no_proxy = ENV[name] || ENV[name.upcase]
    no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
      if /(\A|\.)#{Regexp.quote host}\z/ =~ self.host &&
        (!port || self.port == port.to_i)
        return nil
      end
    }
  end
  URI.parse(proxy_uri)
end
fragment=(v) click to toggle source

Args

v

String

Description

public setter for the fragment component v. (with validation)

see also URI::Generic.check_fragment

Usage

require 'uri'

uri = URI.parse("http://my.example.com/?id=25#time=1305212049")
uri.fragment = "time=1305212086"
# =>  "time=1305212086"
uri
#=> #<URI::HTTP:0x000000007a81f8 URL:http://my.example.com/?id=25#time=1305212086>

# File lib/uri/generic.rb, line 1041
def fragment=(v)
  check_fragment(v)
  set_fragment(v)
  v
end
hash() click to toggle source
# File lib/uri/generic.rb, line 1506
def hash
  self.component_ary.hash
end
hierarchical?() click to toggle source

Checks if URI has a path

# File lib/uri/generic.rb, line 1050
def hierarchical?
  if @path
    true
  else
    false
  end
end
host=(v) click to toggle source

Args

v

String

Description

public setter for the host component v. (with validation)

see also URI::Generic.check_host

Usage

require 'uri'

uri = URI.parse("http://my.example.com")
uri.host = "foo.com"
# =>  "foo.com"
uri
#=> #<URI::HTTP:0x000000008e89e8 URL:http://foo.com>

# File lib/uri/generic.rb, line 645
def host=(v)
  check_host(v)
  set_host(v)
  v
end
hostname() click to toggle source

extract the host part of the URI and unwrap brackets for IPv6 addresses.

This method is same as #host except brackets for IPv6 (andn future IP) addresses are removed.

u = URI(“http://”) p u.hostname #=> “::1” p u.host #=> “[::1]”

# File lib/uri/generic.rb, line 660
def hostname
  v = self.host
  /\A\[(.*)\]\z/ =~ v ? $1 : v
end
hostname=(v) click to toggle source

set the host part of the URI as the argument with brackets for IPv6 addresses.

This method is same as #host= except the argument can be bare IPv6 address.

u = URI(“foo/bar”) p u.to_s
#=> “foo/bar” u.hostname = “::1” p u.to_s
#=> “href=”http://[::1]/bar“>”

If the arugument seems IPv6 address, it is wrapped by brackets.

# File lib/uri/generic.rb, line 678
def hostname=(v)
  v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v
  self.host = v
end
inspect() click to toggle source
# File lib/uri/generic.rb, line 1566
def inspect
  @@to_s.bind(self).call.sub!(/>\z/) {" URL:#{self}>"}
end
merge(oth) click to toggle source

Args

oth

URI or String

Description

Merges two URI's.

Usage

require 'uri'

uri = URI.parse("http://my.example.com")
p uri.merge("/main.rbx?page=1")
# =>  #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>

# File lib/uri/generic.rb, line 1199
def merge(oth)
  begin
    base, rel = merge0(oth)
  rescue
    raise $!.class, $!.message
  end

  if base == rel
    return base
  end

  authority = rel.userinfo || rel.host || rel.port

  # RFC2396, Section 5.2, 2)
  if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query
    base.set_fragment(rel.fragment) if rel.fragment
    return base
  end

  base.set_query(nil)
  base.set_fragment(nil)

  # RFC2396, Section 5.2, 4)
  if !authority
    base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path
  else
    # RFC2396, Section 5.2, 4)
    base.set_path(rel.path) if rel.path
  end

  # RFC2396, Section 5.2, 7)
  base.set_userinfo(rel.userinfo) if rel.userinfo
  base.set_host(rel.host)         if rel.host
  base.set_port(rel.port)         if rel.port
  base.set_query(rel.query)       if rel.query
  base.set_fragment(rel.fragment) if rel.fragment

  return base
end
Also aliased as: +
merge!(oth) click to toggle source

Args

oth

URI or String

Description

Destructive form of merge

Usage

require 'uri'

uri = URI.parse("http://my.example.com")
uri.merge!("/main.rbx?page=1")
p uri
# =>  #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>

# File lib/uri/generic.rb, line 1171
def merge!(oth)
  t = merge(oth)
  if self == t
    nil
  else
    replace!(t)
    self
  end
end
normalize() click to toggle source

Returns normalized URI

# File lib/uri/generic.rb, line 1420
def normalize
  uri = dup
  uri.normalize!
  uri
end
normalize!() click to toggle source

Destructive version of normalize

# File lib/uri/generic.rb, line 1429
def normalize!
  if path && path == ''
    set_path('/')
  end
  if scheme && scheme != scheme.downcase
    set_scheme(self.scheme.downcase)
  end
  if host && host != host.downcase
    set_host(self.host.downcase)
  end
end
opaque=(v) click to toggle source

Args

v

String

Description

public setter for the opaque component v. (with validation)

see also URI::Generic.check_opaque

# File lib/uri/generic.rb, line 988
def opaque=(v)
  check_opaque(v)
  set_opaque(v)
  v
end
parser() click to toggle source

returns the parser to be used.

Unless a URI::Parser is defined, then DEFAULT_PARSER is used.

# File lib/uri/generic.rb, line 298
def parser
  if !defined?(@parser) || !@parser
    DEFAULT_PARSER
  else
    @parser || DEFAULT_PARSER
  end
end
password() click to toggle source

returns the password component

# File lib/uri/generic.rb, line 587
def password
  @password
end
password=(password) click to toggle source

Args

v

String

Description

public setter for the password component. (with validation)

see also URI::Generic.check_password

Usage

require 'uri'

uri = URI.parse("http://john:S3nsit1ve@my.example.com")
uri.password = "V3ry_S3nsit1ve"
# =>  "V3ry_S3nsit1ve"
uri
#=> #<URI::HTTP:0x00000000881d90 URL:http://john:V3ry_S3nsit1ve@my.example.com>

# File lib/uri/generic.rb, line 512
def password=(password)
  check_password(password)
  set_password(password)
  # returns password
end
path=(v) click to toggle source

Args

v

String

Description

public setter for the path component v. (with validation)

see also URI::Generic.check_path

Usage

require 'uri'

uri = URI.parse("http://my.example.com/pub/files")
uri.path = "/faq/"
# =>  "/faq/"
uri
#=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com/faq/>

# File lib/uri/generic.rb, line 870
def path=(v)
  check_path(v)
  set_path(v)
  v
end
port=(v) click to toggle source

Args

v

String

Description

public setter for the port component v. (with validation)

see also URI::Generic.check_port

Usage

require 'uri'

uri = URI.parse("http://my.example.com")
uri.port = 8080
# =>  8080
uri
#=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com:8080>

# File lib/uri/generic.rb, line 744
def port=(v)
  check_port(v)
  set_port(v)
  port
end
query=(v) click to toggle source

Args

v

String

Description

public setter for the query component v. (with validation)

see also URI::Generic.check_query

Usage

require 'uri'

uri = URI.parse("http://my.example.com/?id=25")
uri.query = "id=1"
# =>  "id=1"
uri
#=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com/?id=1>

# File lib/uri/generic.rb, line 935
def query=(v)
  check_query(v)
  set_query(v)
  v
end
registry=(v) click to toggle source

Args

v

String

Description

public setter for the registry component v. (with validation)

see also URI::Generic.check_registry

# File lib/uri/generic.rb, line 797
def registry=(v)
  check_registry(v)
  set_registry(v)
  v
end
relative?() click to toggle source

Checks if URI is relative

# File lib/uri/generic.rb, line 1073
def relative?
  !absolute?
end
route_from(oth) click to toggle source

Args

oth

URI or String

Description

Calculates relative path from oth to self

Usage

require 'uri'

uri = URI.parse('http://my.example.com/main.rbx?page=1')
p uri.route_from('http://my.example.com')
#=> #<URI::Generic:0x20218858 URL:/main.rbx?page=1>

# File lib/uri/generic.rb, line 1373
def route_from(oth)
  # you can modify `rel', but can not `oth'.
  begin
    oth, rel = route_from0(oth)
  rescue
    raise $!.class, $!.message
  end
  if oth == rel
    return rel
  end

  rel.set_path(route_from_path(oth.path, self.path))
  if rel.path == './' && self.query
    # "./?foo" -> "?foo"
    rel.set_path('')
  end

  return rel
end
Also aliased as: -
route_to(oth) click to toggle source

Args

oth

URI or String

Description

Calculates relative path to oth from self

Usage

require 'uri'

uri = URI.parse('http://my.example.com')
p uri.route_to('http://my.example.com/main.rbx?page=1')
#=> #<URI::Generic:0x2020c2f6 URL:/main.rbx?page=1>

# File lib/uri/generic.rb, line 1413
def route_to(oth)
  parser.send(:convert_to_uri, oth).route_from(self)
end
scheme=(v) click to toggle source

Args

v

String

Description

public setter for the scheme component v. (with validation)

see also URI::Generic.check_scheme

Usage

require 'uri'

uri = URI.parse("http://my.example.com")
uri.scheme = "https"
# =>  "https"
uri
#=> #<URI::HTTP:0x000000008e89e8 URL:https://my.example.com>

# File lib/uri/generic.rb, line 370
def scheme=(v)
  check_scheme(v)
  set_scheme(v)
  v
end
select(*components) click to toggle source

Args

components

Multiple Symbol arguments defined in URI::HTTP

Description

Selects specified components from URI

Usage

require 'uri'

uri = URI.parse('http://myuser:mypass@my.example.com/test.rbx')
p uri.select(:userinfo, :host, :path)
# => ["myuser:mypass", "my.example.com", "/test.rbx"]

# File lib/uri/generic.rb, line 1554
def select(*components)
  components.collect do |c|
    if component.include?(c)
      self.send(c)
    else
      raise ArgumentError,
        "expected of components of #{self.class} (#{self.class.component.join(', ')})"
    end
  end
end
to_s() click to toggle source

Constructs String from URI

# File lib/uri/generic.rb, line 1454
def to_s
  str = ''
  if @scheme
    str << @scheme
    str << ':'
  end

  if @opaque
    str << @opaque

  else
    if @registry
      str << @registry
    else
      if @host
        str << '//'
      end
      if self.userinfo
        str << self.userinfo
        str << '@'
      end
      if @host
        str << @host
      end
      if @port && @port != self.default_port
        str << ':'
        str << @port.to_s
      end
    end

    str << path_query
  end

  if @fragment
    str << '#'
    str << @fragment
  end

  str
end
user() click to toggle source

returns the user component

# File lib/uri/generic.rb, line 582
def user
  @user
end
user=(user) click to toggle source

Args

v

String

Description

public setter for the user component. (with validation)

see also URI::Generic.check_user

Usage

require 'uri'

uri = URI.parse("http://john:S3nsit1ve@my.example.com")
uri.user = "sam"
# =>  "sam"
uri
#=> #<URI::HTTP:0x00000000881d90 URL:http://sam:V3ry_S3nsit1ve@my.example.com>

# File lib/uri/generic.rb, line 483
def user=(user)
  check_user(user)
  set_user(user)
  # returns user
end
userinfo() click to toggle source

returns the userinfo, either as 'user' or 'user:password'

# File lib/uri/generic.rb, line 571
def userinfo
  if @user.nil?
    nil
  elsif @password.nil?
    @user
  else
    @user + ':' + @password
  end
end
userinfo=(userinfo) click to toggle source

Sets userinfo, argument is string like 'name:pass'

# File lib/uri/generic.rb, line 451
def userinfo=(userinfo)
  if userinfo.nil?
    return nil
  end
  check_userinfo(*userinfo)
  set_userinfo(*userinfo)
  # returns userinfo
end

Protected Instance Methods

component_ary() click to toggle source

returns an Array of the components defined from the COMPONENT Array

# File lib/uri/generic.rb, line 1530
def component_ary
  component.collect do |x|
    self.send(x)
  end
end
set_fragment(v) click to toggle source

protected setter for the fragment component v

see also #fragment=

# File lib/uri/generic.rb, line 1013
def set_fragment(v)
  @fragment = v
end
set_host(v) click to toggle source

protected setter for the host component v

see also #host=

# File lib/uri/generic.rb, line 617
def set_host(v)
  @host = v
end
set_opaque(v) click to toggle source

protected setter for the opaque component v

see also #opaque=

# File lib/uri/generic.rb, line 970
def set_opaque(v)
  @opaque = v
end
set_password(v) click to toggle source

protected setter for the password component v

see also #password=

# File lib/uri/generic.rb, line 548
def set_password(v)
  @password = v
  # returns v
end
set_path(v) click to toggle source

protected setter for the path component v

see also #path=

# File lib/uri/generic.rb, line 842
def set_path(v)
  @path = v
end
set_port(v) click to toggle source

protected setter for the port component v

see also #port=

# File lib/uri/generic.rb, line 709
def set_port(v)
  unless !v || v.kind_of?(Fixnum)
    if v.empty?
      v = nil
    else
      v = v.to_i
    end
  end
  @port = v
end
set_query(v) click to toggle source

protected setter for the query component v

see also #query=

# File lib/uri/generic.rb, line 907
def set_query(v)
  @query = v
end
set_registry(v) click to toggle source

protected setter for the registry component v

see also #registry=

# File lib/uri/generic.rb, line 779
def set_registry(v)
  @registry = v
end
set_scheme(v) click to toggle source

protected setter for the scheme component v

see also #scheme=

# File lib/uri/generic.rb, line 342
def set_scheme(v)
  @scheme = v ? v.downcase : v
end
set_user(v) click to toggle source

protected setter for the user component v

see also #user=

# File lib/uri/generic.rb, line 538
def set_user(v)
  set_userinfo(v, @password)
  v
end
set_userinfo(user, password = nil) click to toggle source

protect setter for the user component, and password if available. (with validation)

see also #userinfo=

# File lib/uri/generic.rb, line 523
def set_userinfo(user, password = nil)
  unless password
    user, password = split_userinfo(user)
  end
  @user     = user
  @password = password if password

  [@user, @password]
end


class URI::HTTP - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::HTTP

The syntax of HTTP URIs is defined in RFC1738 section 3.3.

Note that the Ruby URI library allows HTTP URLs containing usernames and passwords. This is not legal as per the RFC, but used to be supported in Internet Explorer 5 and 6, before the MS04-004 security update. See <URL:support.microsoft.com/kb/834489>.

In Files

  • lib/open-uri.rb
  • lib/uri/http.rb

Parent

URI::Generic

Included Modules

  • OpenURI::OpenRead

Constants

COMPONENT

An Array of the available components for URI::HTTP

DEFAULT_PORT

A Default port of 80 for URI::HTTP

Public Class Methods

build(args) click to toggle source

Description

Create a new URI::HTTP object from components, with syntax checking.

The components accepted are userinfo, host, port, path, query and fragment.

The components should be provided either as an Array, or as a Hash with keys formed by preceding the component names with a colon.

If an Array is used, the components must be passed in the order [userinfo, host, port, path, query, fragment].

Example:

newuri = URI::HTTP.build({:host => 'www.example.com',
  :path => '/foo/bar'})

newuri = URI::HTTP.build([nil, "www.example.com", nil, "/path",
  "query", 'fragment'])

Currently, if passed userinfo components this method generates invalid HTTP URIs as per RFC 1738.

# File lib/uri/http.rb, line 60
def self.build(args)
  tmp = Util::make_components_hash(self, args)
  return super(tmp)
end
new(*arg) click to toggle source

Description

Create a new URI::HTTP object from generic URI components as per RFC 2396. No HTTP-specific syntax checking (as per RFC 1738) is performed.

Arguments are scheme, userinfo, host, port, registry, path, opaque, query and fragment, in that order.

Example:

uri = URI::HTTP.new('http', nil, "www.example.com", nil, "/path",
  "query", 'fragment')

See also URI::Generic.new

# File lib/uri/http.rb, line 83
def initialize(*arg)
  super(*arg)
end

Public Instance Methods

request_uri() click to toggle source

Description

Returns the full path for an HTTP request, as required by Net::HTTP::Get.

If the URI contains a query, the full path is URI#path + '?' + URI#query. Otherwise, the path is simply URI#path.

# File lib/uri/http.rb, line 95
def request_uri
  r = path_query
  if r && r[0] != /
    r = '/' + r
  end

  r
end


class URI::HTTPS - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::HTTPS

The default port for HTTPS URIs is 443, and the scheme is 'https:' rather than 'http:'. Other than that, HTTPS URIs are identical to HTTP URIs; see URI::HTTP.

In Files

  • lib/uri/https.rb

Parent

URI::HTTP

Constants

DEFAULT_PORT

A Default port of 443 for URI::HTTPS


class URI::InvalidComponentError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::InvalidComponentError

Not a URI component.

In Files

  • lib/uri/common.rb

Parent

URI::Error


class URI::InvalidURIError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::InvalidURIError

Not a URI.

In Files

  • lib/uri/common.rb

Parent

URI::Error


class URI::LDAP - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::LDAP

LDAP URI SCHEMA (described in RFC2255) -->

In Files

  • lib/uri/ldap.rb

Parent

URI::Generic

Constants

COMPONENT

An Array of the available components for URI::LDAP

DEFAULT_PORT

A Default port of 389 for URI::LDAP

SCOPE

Scopes available for the starting point.

  • SCOPE_BASE - the Base DN

  • SCOPE_ONE - one level under the Base DN, not including the base DN and

    not including any entries under this.

  • SCOPE_SUB - subtress, all entries at all levels

Public Class Methods

build(args) click to toggle source

Description

Create a new URI::LDAP object from components, with syntax checking.

The components accepted are host, port, dn, attributes, scope, filter, and extensions.

The components should be provided either as an Array, or as a Hash with keys formed by preceding the component names with a colon.

If an Array is used, the components must be passed in the order [host, port, dn, attributes, scope, filter, extensions].

Example:

newuri = URI::LDAP.build({:host => 'ldap.example.com',
  :dn> => '/dc=example'})

newuri = URI::LDAP.build(["ldap.example.com", nil,
  "/dc=example;dc=com", "query", nil, nil, nil])

# File lib/uri/ldap.rb, line 73
def self.build(args)
  tmp = Util::make_components_hash(self, args)

  if tmp[:dn]
    tmp[:path] = tmp[:dn]
  end

  query = []
  [:extensions, :filter, :scope, :attributes].collect do |x|
    next if !tmp[x] && query.size == 0
    query.unshift(tmp[x])
  end

  tmp[:query] = query.join('?')

  return super(tmp)
end
new(*arg) click to toggle source

Description

Create a new URI::LDAP object from generic URI components as per RFC 2396. No LDAP-specific syntax checking is performed.

Arguments are scheme, userinfo, host, port, registry, path, opaque, query and fragment, in that order.

Example:

uri = URI::LDAP.new("ldap", nil, "ldap.example.com", nil,
  "/dc=example;dc=com", "query", nil, nil, nil, nil)

See also URI::Generic.new

# File lib/uri/ldap.rb, line 108
def initialize(*arg)
  super(*arg)

  if @fragment
    raise InvalidURIError, 'bad LDAP URL'
  end

  parse_dn
  parse_query
end

Public Instance Methods

attributes() click to toggle source

returns attributes.

# File lib/uri/ldap.rb, line 177
def attributes
  @attributes
end
attributes=(val) click to toggle source

setter for attributes val

# File lib/uri/ldap.rb, line 190
def attributes=(val)
  set_attributes(val)
  val
end
dn() click to toggle source

returns dn.

# File lib/uri/ldap.rb, line 158
def dn
  @dn
end
dn=(val) click to toggle source

setter for dn val

# File lib/uri/ldap.rb, line 171
def dn=(val)
  set_dn(val)
  val
end
extensions() click to toggle source

returns extensions.

# File lib/uri/ldap.rb, line 234
def extensions
  @extensions
end
extensions=(val) click to toggle source

setter for extensions val

# File lib/uri/ldap.rb, line 247
def extensions=(val)
  set_extensions(val)
  val
end
filter() click to toggle source

returns filter.

# File lib/uri/ldap.rb, line 215
def filter
  @filter
end
filter=(val) click to toggle source

setter for filter val

# File lib/uri/ldap.rb, line 228
def filter=(val)
  set_filter(val)
  val
end
hierarchical?() click to toggle source

Checks if URI has a path For URI::LDAP this will return false

# File lib/uri/ldap.rb, line 254
def hierarchical?
  false
end
scope() click to toggle source

returns scope.

# File lib/uri/ldap.rb, line 196
def scope
  @scope
end
scope=(val) click to toggle source

setter for scope val

# File lib/uri/ldap.rb, line 209
def scope=(val)
  set_scope(val)
  val
end

Protected Instance Methods

set_attributes(val) click to toggle source

private setter for attributes val

# File lib/uri/ldap.rb, line 182
def set_attributes(val)
  @attributes = val
  build_path_query
  @attributes
end
set_dn(val) click to toggle source

private setter for dn val

# File lib/uri/ldap.rb, line 163
def set_dn(val)
  @dn = val
  build_path_query
  @dn
end
set_extensions(val) click to toggle source

private setter for extensions val

# File lib/uri/ldap.rb, line 239
def set_extensions(val)
  @extensions = val
  build_path_query
  @extensions
end
set_filter(val) click to toggle source

private setter for filter val

# File lib/uri/ldap.rb, line 220
def set_filter(val)
  @filter = val
  build_path_query
  @filter
end
set_scope(val) click to toggle source

private setter for scope val

# File lib/uri/ldap.rb, line 201
def set_scope(val)
  @scope = val
  build_path_query
  @scope
end


class URI::LDAPS - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::LDAPS

The default port for LDAPS URIs is 636, and the scheme is 'ldaps:' rather than 'ldap:'. Other than that, LDAPS URIs are identical to LDAP URIs; see URI::LDAP.

In Files

  • lib/uri/ldaps.rb

Parent

URI::LDAP

Constants

DEFAULT_PORT

A Default port of 636 for URI::LDAPS


class URI::MailTo - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::MailTo

RFC2368, The mailto URL scheme

In Files

  • lib/uri/mailto.rb

Parent

URI::Generic

Included Modules

  • URI::REGEXP

Constants

COMPONENT

An Array of the available components for URI::MailTo

DEFAULT_PORT

A Default port of nil for URI::MailTo

Attributes

headers[R]

E-mail headers set by the URL, as an Array of Arrays

to[R]

The primary e-mail address of the URL, as a String

Public Class Methods

build(args) click to toggle source

Description

Creates a new URI::MailTo object from components, with syntax checking.

Components can be provided as an Array or Hash. If an Array is used, the components must be supplied as [to, headers].

If a Hash is used, the keys are the component names preceded by colons.

The headers can be supplied as a pre-encoded string, such as “subject=subscribe&cc=address”, or as an Array of Arrays like

['subject', 'subscribe'], ['cc', 'address']

Examples:

require 'uri'

m1 = URI::MailTo.build(['joe@example.com', 'subject=Ruby'])
puts m1.to_s  ->  mailto:joe@example.com?subject=Ruby

m2 = URI::MailTo.build(['john@example.com', [['Subject', 'Ruby'], ['Cc', 'jack@example.com']]])
puts m2.to_s  ->  mailto:john@example.com?Subject=Ruby&Cc=jack@example.com

m3 = URI::MailTo.build({:to => 'listman@example.com', :headers => [['subject', 'subscribe']]})
puts m3.to_s  ->  mailto:listman@example.com?subject=subscribe

# File lib/uri/mailto.rb, line 91
def self.build(args)
  tmp = Util::make_components_hash(self, args)

  if tmp[:to]
    tmp[:opaque] = tmp[:to]
  else
    tmp[:opaque] = ''
  end

  if tmp[:headers]
    tmp[:opaque] << '?'

    if tmp[:headers].kind_of?(Array)
      tmp[:opaque] << tmp[:headers].collect { |x|
        if x.kind_of?(Array)
          x[0] + '=' + x[1..-1].join
        else
          x.to_s
        end
      }.join('&')

    elsif tmp[:headers].kind_of?(Hash)
      tmp[:opaque] << tmp[:headers].collect { |h,v|
        h + '=' + v
      }.join('&')

    else
      tmp[:opaque] << tmp[:headers].to_s
    end
  end

  return super(tmp)
end
new(*arg) click to toggle source

Description

Creates a new URI::MailTo object from generic URL components with no syntax checking.

This method is usually called from URI.parse, which checks the validity of each component.

# File lib/uri/mailto.rb, line 134
def initialize(*arg)
  super(*arg)

  @to = nil
  @headers = []

  if MAILTO_REGEXP =~ @opaque
    if arg[-1]
      self.to = $1
      self.headers = $2
    else
      set_to($1)
      set_headers($2)
    end

  else
    raise InvalidComponentError,
      "unrecognised opaque part for mailtoURL: #{@opaque}"
  end
end

Public Instance Methods

headers=(v) click to toggle source

setter for headers v

# File lib/uri/mailto.rb, line 219
def headers=(v)
  check_headers(v)
  set_headers(v)
  v
end
to=(v) click to toggle source

setter for to v

# File lib/uri/mailto.rb, line 184
def to=(v)
  check_to(v)
  set_to(v)
  v
end
to_mailtext() click to toggle source

Returns the RFC822 e-mail text equivalent of the URL, as a String.

Example:

require 'uri'

uri = URI.parse("mailto:ruby-list@ruby-lang.org?Subject=subscribe&cc=myaddr")
uri.to_mailtext
# => "To: ruby-list@ruby-lang.org\nSubject: subscribe\nCc: myaddr\n\n\n"

# File lib/uri/mailto.rb, line 255
    def to_mailtext
      to = parser.unescape(@to)
      head = ''
      body = ''
      @headers.each do |x|
        case x[0]
        when 'body'
          body = parser.unescape(x[1])
        when 'to'
          to << ', ' + parser.unescape(x[1])
        else
          head << parser.unescape(x[0]).capitalize + ': ' +
            parser.unescape(x[1])  + "\n"
        end
      end

      return "To: #{to}
#{head}
#{body}
"
    end
Also aliased as: to_rfc822text
to_rfc822text() click to toggle source
Alias for: to_mailtext
to_s() click to toggle source

Constructs String from URI

# File lib/uri/mailto.rb, line 226
def to_s
  @scheme + ':' +
    if @to
      @to
    else
      ''
    end +
    if @headers.size > 0
      '?' + @headers.collect{|x| x.join('=')}.join('&')
    else
      ''
    end +
    if @fragment
      '#' + @fragment
    else
      ''
    end
end

Protected Instance Methods

set_headers(v) click to toggle source

private setter for headers v

# File lib/uri/mailto.rb, line 208
def set_headers(v)
  @headers = []
  if v
    v.scan(HEADER_REGEXP) do |x|
      @headers << x.split(/=/, 2)
    end
  end
end
set_to(v) click to toggle source

private setter for to v

# File lib/uri/mailto.rb, line 178
def set_to(v)
  @to = v
end


class URI::Parser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class URI::Parser

class that Parses String's into URI's

It contains a Hash set of patterns and Regexp's that match and validate.

In Files

  • lib/uri/common.rb

Parent

Object

Included Modules

  • URI::REGEXP

Attributes

pattern[R]

The Hash of patterns.

see also URI::Parser.initialize_pattern

regexp[R]

The Hash of Regexp

see also URI::Parser.initialize_regexp

Public Class Methods

new(opts = {}) click to toggle source

Synopsis

URI::Parser.new([opts])

Args

The constructor accepts a hash as options for parser. Keys of options are pattern names of URI components and values of options are pattern strings. The constructor generetes set of regexps for parsing URIs.

You can use the following keys:

* :ESCAPED (URI::PATTERN::ESCAPED in default)
* :UNRESERVED (URI::PATTERN::UNRESERVED in default)
* :DOMLABEL (URI::PATTERN::DOMLABEL in default)
* :TOPLABEL (URI::PATTERN::TOPLABEL in default)
* :HOSTNAME (URI::PATTERN::HOSTNAME in default)

Examples

p = URI::Parser.new(:ESCAPED => "(?:%[a-fA-F0-9]{2}|%u[a-fA-F0-9]{4})")
u = p.parse("http://example.jp/%uABCD") #=> #<URI::HTTP:0xb78cf4f8 URL:http://example.jp/%uABCD>
URI.parse(u.to_s) #=> raises URI::InvalidURIError

s = "http://examle.com/ABCD"
u1 = p.parse(s) #=> #<URI::HTTP:0xb78c3220 URL:http://example.com/ABCD>
u2 = URI.parse(s) #=> #<URI::HTTP:0xb78b6d54 URL:http://example.com/ABCD>
u1 == u2 #=> true
u1.eql?(u2) #=> false

# File lib/uri/common.rb, line 99
def initialize(opts = {})
  @pattern = initialize_pattern(opts)
  @pattern.each_value {|v| v.freeze}
  @pattern.freeze

  @regexp = initialize_regexp(@pattern)
  @regexp.each_value {|v| v.freeze}
  @regexp.freeze
end

Public Instance Methods

escape( str ) click to toggle source
escape( str, unsafe )

Args

str

String to make safe

unsafe

Regexp to apply. Defaults to self.regexp

Description

constructs a safe String from str, removing unsafe characters, replacing them with codes.

# File lib/uri/common.rb, line 299
def escape(str, unsafe = @regexp[:UNSAFE])
  unless unsafe.kind_of?(Regexp)
    # perhaps unsafe is String object
    unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false)
  end
  str.gsub(unsafe) do
    us = $&
    tmp = ''
    us.each_byte do |uc|
      tmp << sprintf('%%%02X', uc)
    end
    tmp
  end.force_encoding(Encoding::US_ASCII)
end
extract( str ) click to toggle source
extract( str, schemes )
extract( str, schemes ) {|item| block }

Args

str

String to search

schemes

Patterns to apply to str

Description

Attempts to parse and merge a set of URIs If no block given , then returns the result, else it calls block for each element in result.

see also #make_regexp

# File lib/uri/common.rb, line 261
def extract(str, schemes = nil)
  if block_given?
    str.scan(make_regexp(schemes)) { yield $& }
    nil
  else
    result = []
    str.scan(make_regexp(schemes)) { result.push $& }
    result
  end
end
inspect() click to toggle source
# File lib/uri/common.rb, line 335
def inspect
  @@to_s.bind(self).call
end
join(*uris) click to toggle source

Args

uris

an Array of Strings

Description

Attempts to parse and merge a set of URIs

# File lib/uri/common.rb, line 235
def join(*uris)
  uris[0] = convert_to_uri(uris[0])
  uris.inject :merge
end
make_regexp(schemes = nil) click to toggle source

returns Regexp that is default self.regexp, unless schemes is provided. Then it is a Regexp.union with self.pattern

# File lib/uri/common.rb, line 274
def make_regexp(schemes = nil)
  unless schemes
    @regexp[:ABS_URI_REF]
  else
    /(?=#{Regexp.union(*schemes)}:)#{@pattern[:X_ABS_URI]}/
  end
end
parse(uri) click to toggle source

Args

uri

String

Description

parses uri and constructs either matching URI scheme object (FTP, HTTP, HTTPS, LDAP, LDAPS, or MailTo) or URI::Generic

Usage

p = URI::Parser.new
p.parse("ldap://ldap.example.com/dc=example?user=john")
#=> #<URI::LDAP:0x00000000b9e7e8 URL:ldap://ldap.example.com/dc=example?user=john>

# File lib/uri/common.rb, line 209
def parse(uri)
  scheme, userinfo, host, port,
    registry, path, opaque, query, fragment = self.split(uri)

  if scheme && URI.scheme_list.include?(scheme.upcase)
    URI.scheme_list[scheme.upcase].new(scheme, userinfo, host, port,
                                       registry, path, opaque, query,
                                       fragment, self)
  else
    Generic.new(scheme, userinfo, host, port,
                registry, path, opaque, query,
                fragment, self)
  end
end
split(uri) click to toggle source

Returns a split URI against regexp

# File lib/uri/common.rb, line 120
def split(uri)
  case uri
  when ''
    # null uri

  when @regexp[:ABS_URI]
    scheme, opaque, userinfo, host, port,
      registry, path, query, fragment = $~[1..-1]

    # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]

    # absoluteURI   = scheme ":" ( hier_part | opaque_part )
    # hier_part     = ( net_path | abs_path ) [ "?" query ]
    # opaque_part   = uric_no_slash *uric

    # abs_path      = "/"  path_segments
    # net_path      = "//" authority [ abs_path ]

    # authority     = server | reg_name
    # server        = [ [ userinfo "@" ] hostport ]

    if !scheme
      raise InvalidURIError,
        "bad URI(absolute but no scheme): #{uri}"
    end
    if !opaque && (!path && (!host && !registry))
      raise InvalidURIError,
        "bad URI(absolute but no path): #{uri}"
    end

  when @regexp[:REL_URI]
    scheme = nil
    opaque = nil

    userinfo, host, port, registry,
      rel_segment, abs_path, query, fragment = $~[1..-1]
    if rel_segment && abs_path
      path = rel_segment + abs_path
    elsif rel_segment
      path = rel_segment
    elsif abs_path
      path = abs_path
    end

    # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]

    # relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ]

    # net_path      = "//" authority [ abs_path ]
    # abs_path      = "/"  path_segments
    # rel_path      = rel_segment [ abs_path ]

    # authority     = server | reg_name
    # server        = [ [ userinfo "@" ] hostport ]

  else
    raise InvalidURIError, "bad URI(is not URI?): #{uri}"
  end

  path = '' if !path && !opaque # (see RFC2396 Section 5.2)
  ret = [
    scheme,
    userinfo, host, port,         # X
    registry,                     # X
    path,                         # Y
    opaque,                       # Y
    query,
    fragment
  ]
  return ret
end
unescape( str ) click to toggle source
unescape( str, unsafe )

Args

str

String to remove escapes from

unsafe

Regexp to apply. Defaults to self.regexp

Description

Removes escapes from str

# File lib/uri/common.rb, line 330
def unescape(str, escaped = @regexp[:ESCAPED])
  str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(str.encoding)
end


module URI::REGEXP - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module URI::REGEXP

Includes URI::REGEXP::PATTERN

In Files

  • lib/uri/common.rb


module URI::REGEXP::PATTERN - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module URI::REGEXP::PATTERN

Patterns used to parse URI's

In Files

  • lib/uri/common.rb


class Vector - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Vector

The Vector class represents a mathematical vector, which is useful in its own right, and also constitutes a row or column of a Matrix.

Method Catalogue

To create a Vector:

  • Vector.[](*array)

  • ::elements(array, copy = true)

To access elements:

  • #[](i)

To enumerate the elements:

  • each2(v)

  • collect2(v)

Vector arithmetic:

  • #*(x) “is matrix or number”

  • #+(v)

  • #-(v)

Vector functions:

  • inner_product(v)

  • collect

  • magnitude

  • map

  • map2(v)

  • norm

  • normalize

  • r

  • size

Conversion to other data types:

  • covector

  • to_a

  • coerce(other)

String representations:

  • to_s

  • inspect

In Files

  • lib/matrix.rb

Parent

Object

Included Modules

  • Enumerable

Attributes

elements[R]

INSTANCE CREATION

Public Class Methods

[](*array) click to toggle source

Creates a Vector from a list of elements.

Vector[7, 4, ...]
# File lib/matrix.rb, line 1554
def Vector.[](*array)
  new convert_to_array(array, false)
end
elements(array, copy = true) click to toggle source

Creates a vector from an Array. The optional second argument specifies whether the array itself or a copy is used internally.

# File lib/matrix.rb, line 1562
def Vector.elements(array, copy = true)
  new convert_to_array(array, copy)
end
new(array) click to toggle source

::new is private; use Vector[] or ::elements to create.

# File lib/matrix.rb, line 1569
def initialize(array)
  # No checking is done at this point.
  @elements = array
end

Public Instance Methods

*(x) click to toggle source

Multiplies the vector by x, where x is a number or another vector.

# File lib/matrix.rb, line 1676
def *(x)
  case x
  when Numeric
    els = @elements.collect{|e| e * x}
    self.class.elements(els, false)
  when Matrix
    Matrix.column_vector(self) * x
  when Vector
    Vector.Raise ErrOperationNotDefined, "*", self.class, x.class
  else
    apply_through_coercion(x, __method__)
  end
end
+(v) click to toggle source

Vector addition.

# File lib/matrix.rb, line 1693
def +(v)
  case v
  when Vector
    Vector.Raise ErrDimensionMismatch if size != v.size
    els = collect2(v) {|v1, v2|
      v1 + v2
    }
    self.class.elements(els, false)
  when Matrix
    Matrix.column_vector(self) + v
  else
    apply_through_coercion(v, __method__)
  end
end
-(v) click to toggle source

Vector subtraction.

# File lib/matrix.rb, line 1711
def -(v)
  case v
  when Vector
    Vector.Raise ErrDimensionMismatch if size != v.size
    els = collect2(v) {|v1, v2|
      v1 - v2
    }
    self.class.elements(els, false)
  when Matrix
    Matrix.column_vector(self) - v
  else
    apply_through_coercion(v, __method__)
  end
end
/(x) click to toggle source

Vector division.

# File lib/matrix.rb, line 1729
def /(x)
  case x
  when Numeric
    els = @elements.collect{|e| e / x}
    self.class.elements(els, false)
  when Matrix, Vector
    Vector.Raise ErrOperationNotDefined, "/", self.class, x.class
  else
    apply_through_coercion(x, __method__)
  end
end
==(other) click to toggle source

Returns true iff the two vectors have the same elements in the same order.

# File lib/matrix.rb, line 1645
def ==(other)
  return false unless Vector === other
  @elements == other.elements
end
[](i) click to toggle source

Returns element number i (starting at zero) of the vector.

# File lib/matrix.rb, line 1579
def [](i)
  @elements[i]
end
Also aliased as: element, component
clone() click to toggle source

Return a copy of the vector.

# File lib/matrix.rb, line 1658
def clone
  self.class.elements(@elements)
end
coerce(other) click to toggle source

The coerce method provides support for Ruby type coercion. This coercion mechanism is used by Ruby to handle mixed-type numeric operations: it is intended to find a compatible common type between the two operands of the operator. See also Numeric#coerce.

# File lib/matrix.rb, line 1842
def coerce(other)
  case other
  when Numeric
    return Matrix::Scalar.new(other), self
  else
    raise TypeError, "#{self.class} can't be coerced into #{other.class}"
  end
end
collect() { |e| ... } click to toggle source

Like Array#collect.

# File lib/matrix.rb, line 1762
def collect(&block) # :yield: e
  return to_enum(:collect) unless block_given?
  els = @elements.collect(&block)
  self.class.elements(els, false)
end
Also aliased as: map
collect2(v) { |e1, e2| ... } click to toggle source

Collects (as in Enumerable#collect) over the elements of this vector and v in conjunction.

# File lib/matrix.rb, line 1629
def collect2(v) # :yield: e1, e2
  raise TypeError, "Integer is not like Vector" if v.kind_of?(Integer)
  Vector.Raise ErrDimensionMismatch if size != v.size
  return to_enum(:collect2, v) unless block_given?
  Array.new(size) do |i|
    yield @elements[i], v[i]
  end
end
component(i) click to toggle source
Alias for: []
covector() click to toggle source

Creates a single-row matrix from this vector.

# File lib/matrix.rb, line 1809
def covector
  Matrix.row_vector(self)
end
each(&block) click to toggle source

Iterate over the elements of this vector

# File lib/matrix.rb, line 1606
def each(&block)
  return to_enum(:each) unless block_given?
  @elements.each(&block)
  self
end
each2(v) { |e1, e2| ... } click to toggle source

Iterate over the elements of this vector and v in conjunction.

# File lib/matrix.rb, line 1615
def each2(v) # :yield: e1, e2
  raise TypeError, "Integer is not like Vector" if v.kind_of?(Integer)
  Vector.Raise ErrDimensionMismatch if size != v.size
  return to_enum(:each2, v) unless block_given?
  size.times do |i|
    yield @elements[i], v[i]
  end
  self
end
element(i) click to toggle source
Alias for: []
elements_to_f() click to toggle source
# File lib/matrix.rb, line 1820
def elements_to_f
  warn "#{caller(1)[0]}: warning: Vector#elements_to_f is deprecated"
  map(&:to_f)
end
elements_to_i() click to toggle source
# File lib/matrix.rb, line 1825
def elements_to_i
  warn "#{caller(1)[0]}: warning: Vector#elements_to_i is deprecated"
  map(&:to_i)
end
elements_to_r() click to toggle source
# File lib/matrix.rb, line 1830
def elements_to_r
  warn "#{caller(1)[0]}: warning: Vector#elements_to_r is deprecated"
  map(&:to_r)
end
eql?(other) click to toggle source
# File lib/matrix.rb, line 1650
def eql?(other)
  return false unless Vector === other
  @elements.eql? other.elements
end
hash() click to toggle source

Return a hash-code for the vector.

# File lib/matrix.rb, line 1665
def hash
  @elements.hash
end
inner_product(v) click to toggle source

Returns the inner product of this vector with the other.

Vector[4,7].inner_product Vector[10,1]  => 47

# File lib/matrix.rb, line 1749
def inner_product(v)
  Vector.Raise ErrDimensionMismatch if size != v.size

  p = 0
  each2(v) {|v1, v2|
    p += v1 * v2.conj
  }
  p
end
inspect() click to toggle source

Overrides Object#inspect

# File lib/matrix.rb, line 1865
def inspect
  "Vector" + @elements.inspect
end
magnitude() click to toggle source

Returns the modulus (Pythagorean distance) of the vector.

Vector[5,8,2].r => 9.643650761

# File lib/matrix.rb, line 1773
def magnitude
  Math.sqrt(@elements.inject(0) {|v, e| v + e.abs2})
end
Also aliased as: r, norm
map() click to toggle source
Alias for: collect
map2(v) { |e1, e2| ... } click to toggle source

Like #collect2, but returns a Vector instead of an Array.

# File lib/matrix.rb, line 1782
def map2(v, &block) # :yield: e1, e2
  return to_enum(:map2, v) unless block_given?
  els = collect2(v, &block)
  self.class.elements(els, false)
end
norm() click to toggle source
Alias for: magnitude
normalize() click to toggle source

Returns a new vector with the same direction but with norm 1.

v = Vector[5,8,2].normalize
# => Vector[0.5184758473652127, 0.8295613557843402, 0.20739033894608505]
v.norm => 1.0

# File lib/matrix.rb, line 1796
def normalize
  n = magnitude
  raise ZeroVectorError, "Zero vectors can not be normalized" if n == 0
  self / n
end
r() click to toggle source
Alias for: magnitude
size() click to toggle source

Returns the number of elements in the vector.

# File lib/matrix.rb, line 1595
def size
  @elements.size
end
to_a() click to toggle source

Returns the elements of the vector in an array.

# File lib/matrix.rb, line 1816
def to_a
  @elements.dup
end
to_s() click to toggle source

Overrides Object#to_s

# File lib/matrix.rb, line 1858
def to_s
  "Vector[" + @elements.join(", ") + "]"
end


class Vector::ZeroVectorError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Vector::ZeroVectorError

In Files

  • lib/matrix.rb

Parent

StandardError


module WEBrick - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick

WEB server toolkit.

WEBrick is an HTTP server toolkit that can be configured as an HTTPS server, a proxy server, and a virtual-host server. WEBrick features complete logging of both server operations and HTTP access. WEBrick supports both basic and digest authentication in addition to algorithms not in RFC 2617.

A WEBrick server can be composed of multiple WEBrick servers or servlets to provide differing behavior on a per-host or per-path basis. WEBrick includes servlets for handling CGI scripts, ERb pages, ruby blocks and directory listings.

WEBrick also includes tools for daemonizing a process and starting a process at a higher privilege level and dropping permissions.

Starting an HTTP server

To create a new WEBrick::HTTPServer that will listen to connections on port 8000 and serve documents from the current user's public_html folder:

require 'webrick'

root = File.expand_path '~/public_html'
server = WEBrick::HTTPServer.new :Port => 8000, :DocumentRoot => root

To run the server you will need to provide a suitable shutdown hook as starting the server blocks the current thread:

trap 'INT' do server.shutdown end

server.start

Custom Behavior

The easiest way to have a server perform custom operations is through WEBrick::HTTPServer#mount_proc. The block given will be called with a WEBrick::HTTPRequest with request info and a WEBrick::HTTPResponse which must be filled in appropriately:

server.mount_proc '/' do |req, res|
  res.body = 'Hello, world!'
end

Remember that server.mount_proc must server.start.

Servlets

Advanced custom behavior can be obtained through mounting a subclass of WEBrick::HTTPServlet::AbstractServlet. Servlets provide more modularity when writing an HTTP server than mount_proc allows. Here is a simple servlet:

class Simple < WEBrick::HTTPServlet::AbstractServlet
  def do_GET request, response
    status, content_type, body = do_stuff_with request

    response.status = 200
    response['Content-Type'] = 'text/plain'
    response.body = 'Hello, World!'
  end
end

To initialize the servlet you mount it on the server:

server.mount '/simple', Simple

See WEBrick::HTTPServlet::AbstractServlet for more details.

Virtual Hosts

A server can act as a virtual host for multiple host names. After creating the listening host, additional hosts that do not listen can be created and attached as virtual hosts:

server = WEBrick::HTTPServer.new # ...

vhost = WEBrick::HTTPServer.new :ServerName => 'vhost.example',
                                :DoNotListen => true, # ...
vhost.mount '/', ...

server.virtual_host vhost

If no :DocumentRoot is provided and no servlets or procs are mounted on the main server it will return 404 for all URLs.

HTTPS

To create an HTTPS server you only need to enable SSL and provide an SSL certificate name:

require 'webrick'
require 'webrick/https'

cert_name = [
  %w[CN localhost],
]

server = WEBrick::HTTPServer.new(:Port => 8000,
                                 :SSLEnable => true,
                                 :SSLCertName => cert_name)

This will start the server with a self-generated self-signed certificate. The certificate will be changed every time the server is restarted.

To create a server with a pre-determined key and certificate you can provide them:

require 'webrick'
require 'webrick/https'
require 'openssl'

cert = OpenSSL::X509::Certificate.new File.read '/path/to/cert.pem'
pkey = OpenSSL::PKey::RSA.new File.read '/path/to/pkey.pem'

server = WEBrick::HTTPServer.new(:Port => 8000,
                                 :SSLEnable => true,
                                 :SSLCertificate => cert,
                                 :SSLPrivateKey => pkey)

Proxy Server

WEBrick can act as a proxy server:

require 'webrick'
require 'webrick/httpproxy'

proxy = WEBrick::HTTPProxyServer.new :Port => 8000

trap 'INT' do proxy.shutdown end

See WEBrick::HTTPProxy for further details including modifying proxied responses.

Basic and Digest authentication

WEBrick provides both Basic and Digest authentication for regular and proxy servers. See WEBrick::HTTPAuth, WEBrick::HTTPAuth::BasicAuth and WEBrick::HTTPAuth::DigestAuth.

WEBrick as a Production Web Server

WEBrick can be run as a production server for small loads.

Daemonizing

To start a WEBrick server as a daemon simple run WEBrick::Daemon.start before starting the server.

Dropping Permissions

WEBrick can be started as one user to gain permission to bind to port 80 or 443 for serving HTTP or HTTPS traffic then can drop these permissions for regular operation. To listen on all interfaces for HTTP traffic:

sockets = WEBrick::Utils.create_listeners nil, 80

Then drop privileges:

WEBrick::Utils.su 'www'

Then create a server that does not listen by default:

server = WEBrick::HTTPServer.new :DoNotListen => true, # ...

Then overwrite the listening sockets with the port 80 sockets:

server.listeners.replace sockets

Logging

WEBrick can separately log server operations and end-user access. For server operations:

log_file = File.open '/var/log/webrick.log', 'a+'
log = WEBrick::Log.new log_file

For user access logging:

access_log = [
  [log_file, WEBrick::AccessLog::COMBINED_LOG_FORMAT],
]

server = WEBrick::HTTPServer.new :Logger => log, :AccessLog => access_log

See WEBrick::AccessLog for further log formats.

Log Rotation

To rotate logs in WEBrick on a HUP signal (like syslogd can send), open the log file in 'a+' mode (as above) and trap 'HUP' to reopen the log file:

trap 'HUP' do log_file.reopen '/path/to/webrick.log', 'a+'

Copyright

Author: IPR – Internet Programming with Ruby – writers

Copyright © 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU Copyright © 2002 Internet Programming with Ruby writers. All rights reserved.

In Files

  • lib/webrick/accesslog.rb
  • lib/webrick/cgi.rb
  • lib/webrick/config.rb
  • lib/webrick/cookie.rb
  • lib/webrick/htmlutils.rb
  • lib/webrick/httpauth/authenticator.rb
  • lib/webrick/httpauth/basicauth.rb
  • lib/webrick/httpauth/digestauth.rb
  • lib/webrick/httpauth/htdigest.rb
  • lib/webrick/httpauth/htgroup.rb
  • lib/webrick/httpauth/htpasswd.rb
  • lib/webrick/httpauth/userdb.rb
  • lib/webrick/httpauth.rb
  • lib/webrick/httpproxy.rb
  • lib/webrick/httprequest.rb
  • lib/webrick/httpresponse.rb
  • lib/webrick/https.rb
  • lib/webrick/httpserver.rb
  • lib/webrick/httpservlet/abstract.rb
  • lib/webrick/httpservlet/cgihandler.rb
  • lib/webrick/httpservlet/erbhandler.rb
  • lib/webrick/httpservlet/filehandler.rb
  • lib/webrick/httpservlet/prochandler.rb
  • lib/webrick/httpservlet.rb
  • lib/webrick/httpstatus.rb
  • lib/webrick/httputils.rb
  • lib/webrick/httpversion.rb
  • lib/webrick/log.rb
  • lib/webrick/server.rb
  • lib/webrick/ssl.rb
  • lib/webrick/utils.rb
  • lib/webrick/version.rb
  • lib/webrick.rb

Constants

VERSION

The WEBrick version


module WEBrick::AccessLog - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick::AccessLog

AccessLog provides logging to various files in various formats.

Multiple logs may be written to at the same time:

access_log = [
  [$stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT],
  [$stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT],
]

server = WEBrick::HTTPServer.new :AccessLog => access_log

Custom log formats may be defined. WEBrick::AccessLog provides a subset of the formatting from Apache's mod_log_config httpd.apache.org/docs/mod/mod_log_config.html#formats. See AccessLog::setup_params for a list of supported options

In Files

  • lib/webrick/accesslog.rb

Constants

AGENT_LOG_FORMAT

User-Agent Log Format

CLF

Short alias for Common Log Format

CLF_TIME_FORMAT

The Common Log Format's time format

COMBINED_LOG_FORMAT

Combined Log Format

COMMON_LOG_FORMAT

Common Log Format

REFERER_LOG_FORMAT

Referer Log Format

Public Instance Methods

escape(data) click to toggle source

Escapes control characters in data

# File lib/webrick/accesslog.rb, line 150
def escape(data)
  if data.tainted?
    data.gsub(/[[:cntrl:]\]+/) {$&.dump[1...-1]}.untaint
  else
    data
  end
end
format(format_string, params) click to toggle source

Formats params according to format_string which is described in setup_params.

# File lib/webrick/accesslog.rb, line 122
def format(format_string, params)
  format_string.gsub(/\%(?:\{(.*?)\})?>?([a-zA-Z%])/){
     param, spec = $1, $2
     case spec[0]
     when e, i, n, o
       raise AccessLogError,
         "parameter is required for \"#{spec}\"" unless param
       (param = params[spec][param]) ? escape(param) : "-"
     when t
       params[spec].strftime(param || CLF_TIME_FORMAT)
     when p
       case param
       when 'remote'
         escape(params["i"].peeraddr[1].to_s)
       else
         escape(params["p"].to_s)
       end
     when %
       "%"
     else
       escape(params[spec].to_s)
     end
  }
end
setup_params(config, req, res) click to toggle source

This format specification is a subset of mod_log_config of Apache:

%a

Remote IP address

%b

Total response size

%e{variable}

Given variable in ENV

%f

Response filename

%h

Remote host name

%{header}i

Given request header

%l

Remote logname, always “-”

%m

Request method

%{attr}n

Given request attribute from req.attributes

%{header}o

Given response header

%p

Server's request port

%{format}p

The canonical port of the server serving the request or the actual port or the client's actual port. Valid formats are canonical, local or remote.

%q

Request query string

%r

First line of the request

%s

Request status

%t

Time the request was recieved

%T

Time taken to process the request

%u

Remote user from auth

%U

Unparsed URI

%%

Literal %

# File lib/webrick/accesslog.rb, line 94
def setup_params(config, req, res)
  params = Hash.new("")
  params["a"] = req.peeraddr[3]
  params["b"] = res.sent_size
  params["e"] = ENV
  params["f"] = res.filename || ""
  params["h"] = req.peeraddr[2]
  params["i"] = req
  params["l"] = "-"
  params["m"] = req.request_method
  params["n"] = req.attributes
  params["o"] = res
  params["p"] = req.port
  params["q"] = req.query_string
  params["r"] = req.request_line.sub(/\x0d?\x0a\z/, '')
  params["s"] = res.status       # won't support "%>s"
  params["t"] = req.request_time
  params["T"] = Time.now - req.request_time
  params["u"] = req.user || "-"
  params["U"] = req.unparsed_uri
  params["v"] = config[:ServerName]
  params
end


class WEBrick::AccessLog::AccessLogError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::AccessLog::AccessLogError

Raised if a parameter such as %e, %i, %o or %n is used without fetching a specific field.

In Files

  • lib/webrick/accesslog.rb

Parent

StandardError


class WEBrick::BasicLog - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::BasicLog

A generic logging class

In Files

  • lib/webrick/log.rb

Parent

Object

Constants

DEBUG

Debugging error level for messages used in server development or debugging

ERROR

Error log level which indicates a recoverable error

FATAL

Fatal log level which indicates a server crash

INFO

Information log level which indicates possibly useful information

WARN

Warning log level which indicates a possible problem

Attributes

level[RW]

log-level, messages above this level will be logged

Public Class Methods

new(log_file=nil, level=nil) click to toggle source

Initializes a new logger for log_file that outputs messages at level or higher. log_file can be a filename, an IO-like object that responds to #<< or nil which outputs to $stderr.

If no level is given INFO is chosen by default

# File lib/webrick/log.rb, line 49
def initialize(log_file=nil, level=nil)
  @level = level || INFO
  case log_file
  when String
    @log = open(log_file, "a+")
    @log.sync = true
    @opened = true
  when NilClass
    @log = $stderr
  else
    @log = log_file  # requires "<<". (see BasicLog#log)
  end
end

Public Instance Methods

<<(obj) click to toggle source

Synonym for log(INFO, obj.to_s)

# File lib/webrick/log.rb, line 83
def <<(obj)
  log(INFO, obj.to_s)
end
close() click to toggle source

Closes the logger (also closes the log device associated to the logger)

# File lib/webrick/log.rb, line 65
def close
  @log.close if @opened
  @log = nil
end
debug(msg) click to toggle source

Shortcut for logging a DEBUG message

# File lib/webrick/log.rb, line 96
def debug(msg) log(DEBUG, "DEBUG " << format(msg)); end
debug?() click to toggle source

Will the logger output DEBUG messages?

# File lib/webrick/log.rb, line 107
def debug?; @level >= DEBUG; end
error(msg) click to toggle source

Shortcut for logging an ERROR message

# File lib/webrick/log.rb, line 90
def error(msg) log(ERROR, "ERROR " << format(msg)); end
error?() click to toggle source

Will the logger output ERROR messages?

# File lib/webrick/log.rb, line 101
def error?; @level >= ERROR; end
fatal(msg) click to toggle source

Shortcut for logging a FATAL message

# File lib/webrick/log.rb, line 88
def fatal(msg) log(FATAL, "FATAL " << format(msg)); end
fatal?() click to toggle source

Will the logger output FATAL messages?

# File lib/webrick/log.rb, line 99
def fatal?; @level >= FATAL; end
info(msg) click to toggle source

Shortcut for logging an INFO message

# File lib/webrick/log.rb, line 94
def info(msg)  log(INFO,  "INFO  " << format(msg)); end
info?() click to toggle source

Will the logger output INFO messages?

# File lib/webrick/log.rb, line 105
def info?;  @level >= INFO; end
log(level, data) click to toggle source

Logs data at level if the given level is above the current log level.

# File lib/webrick/log.rb, line 74
def log(level, data)
  if @log && level <= @level
    data += "\n" if /\n\Z/ !~ data
    @log << data
  end
end
warn(msg) click to toggle source

Shortcut for logging a WARN message

# File lib/webrick/log.rb, line 92
def warn(msg)  log(WARN,  "WARN  " << format(msg)); end
warn?() click to toggle source

Will the logger output WARN messages?

# File lib/webrick/log.rb, line 103
def warn?;  @level >= WARN; end


class WEBrick::CGI - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::CGI

A CGI library using WEBrick requests and responses.

Example:

class MyCGI < WEBrick::CGI
  def do_GET req, res
    res.body = 'it worked!'
    res.status = 200
  end
end

MyCGI.new.start

In Files

  • lib/webrick/cgi.rb

Parent

Object

Constants

CGIError

The CGI error exception class

Attributes

config[R]

The CGI configuration. This is based on WEBrick::Config::HTTP

logger[R]

The CGI logger

Public Class Methods

new(*args) click to toggle source

Creates a new CGI interface.

The first argument in args is a configuration hash which would update WEBrick::Config::HTTP.

Any remaining arguments are stored in the @options instance variable for use by a subclass.

# File lib/webrick/cgi.rb, line 55
def initialize(*args)
  if defined?(MOD_RUBY)
    unless ENV.has_key?("GATEWAY_INTERFACE")
      Apache.request.setup_cgi_env
    end
  end
  if %r{HTTP/(\d+\.\d+)} =~ ENV["SERVER_PROTOCOL"]
    httpv = $1
  end
  @config = WEBrick::Config::HTTP.dup.update(
    :ServerSoftware => ENV["SERVER_SOFTWARE"] || "null",
    :HTTPVersion    => HTTPVersion.new(httpv || "1.0"),
    :RunOnCGI       => true,   # to detect if it runs on CGI.
    :NPH            => false   # set true to run as NPH script.
  )
  if config = args.shift
    @config.update(config)
  end
  @config[:Logger] ||= WEBrick::BasicLog.new($stderr)
  @logger = @config[:Logger]
  @options = args
end

Public Instance Methods

[](key) click to toggle source

Reads key from the configuration

# File lib/webrick/cgi.rb, line 81
def [](key)
  @config[key]
end
service(req, res) click to toggle source

Services the request req which will fill in the response res. See WEBrick::HTTPServlet::AbstractServlet#service for details.

# File lib/webrick/cgi.rb, line 156
def service(req, res)
  method_name = "do_" + req.request_method.gsub(/-/, "_")
  if respond_to?(method_name)
    __send__(method_name, req, res)
  else
    raise HTTPStatus::MethodNotAllowed,
          "unsupported method `#{req.request_method}'."
  end
end
start(env=ENV, stdin=$stdin, stdout=$stdout) click to toggle source

Starts the CGI process with the given environment env and standard input and output stdin and stdout.

# File lib/webrick/cgi.rb, line 89
def start(env=ENV, stdin=$stdin, stdout=$stdout)
  sock = WEBrick::CGI::Socket.new(@config, env, stdin, stdout)
  req = HTTPRequest.new(@config)
  res = HTTPResponse.new(@config)
  unless @config[:NPH] or defined?(MOD_RUBY)
    def res.setup_header
      unless @header["status"]
        phrase = HTTPStatus::reason_phrase(@status)
        @header["status"] = "#{@status} #{phrase}"
      end
      super
    end
    def res.status_line
      ""
    end
  end

  begin
    req.parse(sock)
    req.script_name = (env["SCRIPT_NAME"] || File.expand_path($0)).dup
    req.path_info = (env["PATH_INFO"] || "").dup
    req.query_string = env["QUERY_STRING"]
    req.user = env["REMOTE_USER"]
    res.request_method = req.request_method
    res.request_uri = req.request_uri
    res.request_http_version = req.http_version
    res.keep_alive = req.keep_alive?
    self.service(req, res)
  rescue HTTPStatus::Error => ex
    res.set_error(ex)
  rescue HTTPStatus::Status => ex
    res.status = ex.code
  rescue Exception => ex
    @logger.error(ex)
    res.set_error(ex, true)
  ensure
    req.fixup
    if defined?(MOD_RUBY)
      res.setup_header
      Apache.request.status_line = "#{res.status} #{res.reason_phrase}"
      Apache.request.status = res.status
      table = Apache.request.headers_out
      res.header.each{|key, val|
        case key
        when /^content-encoding$/
          Apache::request.content_encoding = val
        when /^content-type$/
          Apache::request.content_type = val
        else
          table[key] = val.to_s
        end
      }
      res.cookies.each{|cookie|
        table.add("Set-Cookie", cookie.to_s)
      }
      Apache.request.send_http_header
      res.send_body(sock)
    else
      res.send_response(sock)
    end
  end
end


module WEBrick::Config - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick::Config

In Files

  • lib/webrick/config.rb
  • lib/webrick/https.rb
  • lib/webrick/ssl.rb

Constants

BasicAuth

Default configuration for WEBrick::HTTPAuth::BasicAuth

:AutoReloadUserDB

Reload the user database provided by :UserDB automatically?

DigestAuth

Default configuration for WEBrick::HTTPAuth::DigestAuth.

:Algorithm

MD5, MD5-sess (default), SHA1, SHA1-sess

:Domain

An Array of URIs that define the protected space

:Qop

'auth' for authentication, 'auth-int' for integrity protection or both

:UseOpaque

Should the server send opaque values to the client? This helps prevent replay attacks.

:CheckNc

Should the server check the nonce count? This helps the server detect replay attacks.

:UseAuthenticationInfoHeader

Should the server send an AuthenticationInfo header?

:AutoReloadUserDB

Reload the user database provided by :UserDB automatically?

:NonceExpirePeriod

How long should we store used nonces? Default is 30 minutes.

:NonceExpireDelta

How long is a nonce valid? Default is 1 minute

:InternetExplorerHack

Hack which allows Internet Explorer to work.

:OperaHack

Hack which allows Opera to work.

FileHandler

Default configuration for WEBrick::HTTPServlet::FileHandler

:AcceptableLanguages

Array of languages allowed for accept-language. There is no default

:DirectoryCallback

Allows preprocessing of directory requests. There is no default callback.

:FancyIndexing

If true, show an index for directories. The default is true.

:FileCallback

Allows preprocessing of file requests. There is no default callback.

:HandlerCallback

Allows preprocessing of requests. There is no default callback.

:HandlerTable

Maps file suffixes to file handlers. DefaultFileHandler is used by default but any servlet can be used.

:NondisclosureName

Do not show files matching this array of globs. .ht* and *~ are excluded by default.

:UserDir

Directory inside ~user to serve content from for /~user requests. Only works if mounted on /. Disabled by default.

General

for GenericServer

HTTP

for HTTPServer, HTTPRequest, HTTPResponse …

SSL

Default SSL server configuration.

WEBrick can automatically create a self-signed certificate if :SSLCertName is set. For more information on the various SSL options see OpenSSL::SSL::SSLContext.

:ServerSoftware

The server software name used in the Server: header.

:SSLEnable

false,

Enable SSL for this server.  Defaults to false.
:SSLCertificate

The SSL certificate for the server.

:SSLPrivateKey

The SSL private key for the server certificate.

:SSLClientCA

nil,

Array of certificates that will be sent to the client.
:SSLExtraChainCert

nil,

Array of certificates that willbe added to the certificate chain
:SSLCACertificateFile

nil,

Path to a CA certificate file
:SSLCACertificatePath

nil,

Path to a directory containing CA certificates
:SSLCertificateStore

nil,

OpenSSL::X509::Store used for certificate validation of the client
:SSLTmpDhCallback

nil,

Callback invoked when DH parameters are required.
:SSLVerifyClient

Sets whether the client is verified. This defaults to VERIFY_NONE which is typical for an HTTPS server.

:SSLVerifyDepth

Number of CA certificates to walk when verifying a certificate chain

:SSLVerifyCallback

Custom certificate verification callback

:SSLTimeout

Maximum session lifetime

:SSLOptions

Various SSL options

:SSLStartImmediately

Immediately start SSL upon connection? Defaults to true

:SSLCertName

SSL certificate name. Must be set to enable automatic certificate creation.

:SSLCertComment

Comment used during automatic certificate creation.


class WEBrick::Cookie - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::Cookie

Processes HTTP cookies

In Files

  • lib/webrick/cookie.rb

Parent

Object

Attributes

comment[RW]

The cookie comment

domain[RW]

The cookie domain

max_age[RW]

The maximum age of the cookie

name[R]

The cookie name

path[RW]

The cookie path

secure[RW]

Is this a secure cookie?

value[RW]

The cookie value

version[RW]

The cookie version

Public Class Methods

new(name, value) click to toggle source

Creates a new cookie with the given name and value

# File lib/webrick/cookie.rb, line 65
def initialize(name, value)
  @name = name
  @value = value
  @version = 0     # Netscape Cookie

  @domain = @path = @secure = @comment = @max_age =
  @expires = @comment_url = @discard = @port = nil
end
parse(str) click to toggle source

Parses a Cookie field sent from the user-agent. Returns an array of cookies.

# File lib/webrick/cookie.rb, line 110
def self.parse(str)
  if str
    ret = []
    cookie = nil
    ver = 0
    str.split(/[;,]\s+/).each{|x|
      key, val = x.split(/=/,2)
      val = val ? HTTPUtils::dequote(val) : ""
      case key
      when "$Version"; ver = val.to_i
      when "$Path";    cookie.path = val
      when "$Domain";  cookie.domain = val
      when "$Port";    cookie.port = val
      else
        ret << cookie if cookie
        cookie = self.new(key, val)
        cookie.version = ver
      end
    }
    ret << cookie if cookie
    ret
  end
end
parse_set_cookie(str) click to toggle source

Parses the cookie in str

# File lib/webrick/cookie.rb, line 137
def self.parse_set_cookie(str)
  cookie_elem = str.split(/;/)
  first_elem = cookie_elem.shift
  first_elem.strip!
  key, value = first_elem.split(/=/, 2)
  cookie = new(key, HTTPUtils.dequote(value))
  cookie_elem.each{|pair|
    pair.strip!
    key, value = pair.split(/=/, 2)
    if value
      value = HTTPUtils.dequote(value.strip)
    end
    case key.downcase
    when "domain"  then cookie.domain  = value
    when "path"    then cookie.path    = value
    when "expires" then cookie.expires = value
    when "max-age" then cookie.max_age = Integer(value)
    when "comment" then cookie.comment = value
    when "version" then cookie.version = Integer(value)
    when "secure"  then cookie.secure = true
    end
  }
  return cookie
end
parse_set_cookies(str) click to toggle source

Parses the cookies in str

# File lib/webrick/cookie.rb, line 165
def self.parse_set_cookies(str)
  return str.split(/,(?=[^;,]*=)|,$/).collect{|c|
    parse_set_cookie(c)
  }
end

Public Instance Methods

expires() click to toggle source

Retrieves the expiration time as a Time

# File lib/webrick/cookie.rb, line 86
def expires
  @expires && Time.parse(@expires)
end
expires=(t) click to toggle source

Sets the cookie expiration to the time t. The expiration time may be a false value to disable expiration or a Time or HTTP format time string to set the expiration date.

# File lib/webrick/cookie.rb, line 79
def expires=(t)
  @expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s)
end
to_s() click to toggle source

The cookie string suitable for use in an HTTP header

# File lib/webrick/cookie.rb, line 93
def to_s
  ret = ""
  ret << @name << "=" << @value
  ret << "; " << "Version=" << @version.to_s if @version > 0
  ret << "; " << "Domain="  << @domain  if @domain
  ret << "; " << "Expires=" << @expires if @expires
  ret << "; " << "Max-Age=" << @max_age.to_s if @max_age
  ret << "; " << "Comment=" << @comment if @comment
  ret << "; " << "Path="    << @path if @path
  ret << "; " << "Secure"   if @secure
  ret
end


class WEBrick::Daemon - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::Daemon

A generic module for daemonizing a process

In Files

  • lib/webrick/server.rb

Parent

Object

Public Class Methods

start() { || ... } click to toggle source

Performs the standard operations for daemonizing a process. Runs a block, if given.

# File lib/webrick/server.rb, line 45
def Daemon.start
  exit!(0) if fork
  Process::setsid
  exit!(0) if fork
  Dir::chdir("/")
  File::umask(0)
  STDIN.reopen("/dev/null")
  STDOUT.reopen("/dev/null", "w")
  STDERR.reopen("/dev/null", "w")
  yield if block_given?
end


class WEBrick::GenericServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::GenericServer

Base TCP server class. You must subclass GenericServer and provide a run method.

In Files

  • lib/webrick/server.rb
  • lib/webrick/ssl.rb

Parent

Object

Attributes

config[R]

The server configuration

listeners[R]

Sockets listening for connections.

logger[R]

The server logger. This is independent from the HTTP access log.

status[R]

The server status. One of :Stop, :Running or :Shutdown

tokens[R]

Tokens control the number of outstanding clients. The :MaxClients configuration sets this.

Public Class Methods

new(config={}, default=Config::General) click to toggle source

Creates a new generic server from config. The default configuration comes from default.

# File lib/webrick/server.rb, line 94
def initialize(config={}, default=Config::General)
  @config = default.dup.update(config)
  @status = :Stop
  @config[:Logger] ||= Log::new
  @logger = @config[:Logger]

  @tokens = SizedQueue.new(@config[:MaxClients])
  @config[:MaxClients].times{ @tokens.push(nil) }

  webrickv = WEBrick::VERSION
  rubyv = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
  @logger.info("WEBrick #{webrickv}")
  @logger.info("ruby #{rubyv}")

  @listeners = []
  unless @config[:DoNotListen]
    if @config[:Listen]
      warn(":Listen option is deprecated; use GenericServer#listen")
    end
    listen(@config[:BindAddress], @config[:Port])
    if @config[:Port] == 0
      @config[:Port] = @listeners[0].addr[1]
    end
  end
end

Public Instance Methods

[](key) click to toggle source

Retrieves key from the configuration

# File lib/webrick/server.rb, line 123
def [](key)
  @config[key]
end
listen(address, port) click to toggle source

Adds listeners from address and port to the server. See WEBrick::Utils.create_listeners for details.

# File lib/webrick/server.rb, line 131
def listen(address, port)
  @listeners += Utils::create_listeners(address, port, @logger)
end
run(sock) click to toggle source

You must subclass GenericServer and implement #run which accepts a TCP client socket

# File lib/webrick/server.rb, line 246
def run(sock)
  @logger.fatal "run() must be provided by user."
end
shutdown() click to toggle source

Shuts down the server and all listening sockets. New listeners must be provided to restart the server.

# File lib/webrick/server.rb, line 219
def shutdown
  stop
  @listeners.each{|s|
    if @logger.debug?
      addr = s.addr
      @logger.debug("close TCPSocket(#{addr[2]}, #{addr[1]})")
    end
    begin
      s.shutdown
    rescue Errno::ENOTCONN
      # when `Errno::ENOTCONN: Socket is not connected' on some platforms,
      # call #close instead of #shutdown.
      # (ignore @config[:ShutdownSocketWithoutClose])
      s.close
    else
      unless @config[:ShutdownSocketWithoutClose]
        s.close
      end
    end
  }
  @listeners.clear
end
start(&block) click to toggle source

Starts the server and runs the block for each connection. This method does not return until the server is stopped from a signal handler or another thread using stop or shutdown.

If the block raises a subclass of StandardError the exception is logged and ignored. If an IOError or Errno::EBADF exception is raised the exception is ignored. If an Exception subclass is raised the exception is logged and re-raised which stops the server.

To completely shut down a server call shutdown from ensure:

server = WEBrick::GenericServer.new
# or WEBrick::HTTPServer.new

begin
  server.start
ensure
  server.shutdown
end
# File lib/webrick/server.rb, line 156
def start(&block)
  raise ServerError, "already started." if @status != :Stop
  server_type = @config[:ServerType] || SimpleServer

  server_type.start{
    @logger.info            "#{self.class}#start: pid=#{$$} port=#{@config[:Port]}"
    call_callback(:StartCallback)

    thgroup = ThreadGroup.new
    @status = :Running
    begin
      while @status == :Running
        begin
          if svrs = IO.select(@listeners, nil, nil, 2.0)
            svrs[0].each{|svr|
              @tokens.pop          # blocks while no token is there.
              if sock = accept_client(svr)
                sock.do_not_reverse_lookup = config[:DoNotReverseLookup]
                th = start_thread(sock, &block)
                th[:WEBrickThread] = true
                thgroup.add(th)
              else
                @tokens.push(nil)
              end
            }
          end
        rescue Errno::EBADF, IOError => ex
          # if the listening socket was closed in GenericServer#shutdown,
          # IO::select raise it.
        rescue StandardError => ex
          msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
          @logger.error msg
        rescue Exception => ex
          @logger.fatal ex
          raise
        end
      end

    ensure
      @status = :Shutdown
      @logger.info "going to shutdown ..."
      thgroup.list.each{|th| th.join if th[:WEBrickThread] }
      call_callback(:StopCallback)
      @logger.info "#{self.class}#start done."
      @status = :Stop
    end
  }
end
stop() click to toggle source

Stops the server from accepting new connections.

# File lib/webrick/server.rb, line 209
def stop
  if @status == :Running
    @status = :Shutdown
  end
end


module WEBrick::HTMLUtils - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick::HTMLUtils

In Files

  • lib/webrick/htmlutils.rb

Public Class Methods

escape(string) click to toggle source

Escapes &, “, > and < in string

# File lib/webrick/htmlutils.rb, line 17
def escape(string)
  return "" unless string
  str = string.b
  str.gsub!(/&/, '&amp;')
  str.gsub!(/\"/, '&quot;')
  str.gsub!(/>/, '&gt;')
  str.gsub!(/</, '&lt;')
  str.force_encoding(string.encoding)
end


module WEBrick::HTTPAuth - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick::HTTPAuth

HTTPAuth provides both basic and digest authentication.

To enable authentication for requests in WEBrick you will need a user database and an authenticator. To start, here's an Htpasswd database for use with a DigestAuth authenticator:

config = { :Realm => 'DigestAuth example realm' }

htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file'
htpasswd.auth_type = WEBrick::HTTPAuth::DigestAuth
htpasswd.set_passwd config[:Realm], 'username', 'password'
htpasswd.flush

The :Realm is used to provide different access to different groups across several resources on a server. Typically you'll need only one realm for a server.

This database can be used to create an authenticator:

config[:UserDB] = htpasswd

digest_auth = WEBrick::HTTPAuth::DigestAuth.new config

To authenticate a request call authenticate with a request and response object in a servlet:

def do_GET req, res
  @authenticator.authenticate req, res
end

For digest authentication the authenticator must not be created every request, it must be passed in as an option via WEBrick::HTTPServer#mount.

In Files

  • lib/webrick/httpauth/authenticator.rb
  • lib/webrick/httpauth/basicauth.rb
  • lib/webrick/httpauth/digestauth.rb
  • lib/webrick/httpauth/htdigest.rb
  • lib/webrick/httpauth/htgroup.rb
  • lib/webrick/httpauth/htpasswd.rb
  • lib/webrick/httpauth/userdb.rb
  • lib/webrick/httpauth.rb

Public Instance Methods

basic_auth(req, res, realm) { |username, password| ... } click to toggle source

Simple wrapper for providing basic authentication for a request. When called with a request req, response res, authentication realm and block the block will be called with a username and password. If the block returns true the request is allowed to continue, otherwise an HTTPStatus::Unauthorized error is raised.

# File lib/webrick/httpauth.rb, line 78
def basic_auth(req, res, realm, &block) # :yield: username, password
  _basic_auth(req, res, realm, "Authorization", "WWW-Authenticate",
              HTTPStatus::Unauthorized, block)
end
proxy_basic_auth(req, res, realm) { |username, password| ... } click to toggle source

Simple wrapper for providing basic authentication for a proxied request. When called with a request req, response res, authentication realm and block the block will be called with a username and password. If the block returns true the request is allowed to continue, otherwise an HTTPStatus::ProxyAuthenticationRequired error is raised.

# File lib/webrick/httpauth.rb, line 90
def proxy_basic_auth(req, res, realm, &block) # :yield: username, password
  _basic_auth(req, res, realm, "Proxy-Authorization", "Proxy-Authenticate",
              HTTPStatus::ProxyAuthenticationRequired, block)
end


module WEBrick::HTTPAuth::Authenticator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick::HTTPAuth::Authenticator

Module providing generic support for both Digest and Basic authentication schemes.

In Files

  • lib/webrick/httpauth/authenticator.rb

Constants

AuthScheme

Method of authentication, must be overridden by the including class

Attributes

logger[R]

The logger for this authenticator

realm[R]

The realm this authenticator covers

userdb[R]

The user database for this authenticator


class WEBrick::HTTPAuth::BasicAuth - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPAuth::BasicAuth

Basic Authentication for WEBrick

Use this class to add basic authentication to a WEBrick servlet.

Here is an example of how to set up a BasicAuth:

config = { :Realm => 'BasicAuth example realm' }

htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file'
htpasswd.set_passwd config[:Realm], 'username', 'password'
htpasswd.flush

config[:UserDB] = htpasswd

basic_auth = WEBrick::HTTPAuth::BasicAuth.new config

In Files

  • lib/webrick/httpauth/basicauth.rb

Parent

Object

Included Modules

  • WEBrick::HTTPAuth::Authenticator

Attributes

logger[R]
realm[R]
userdb[R]

Public Class Methods

make_passwd(realm, user, pass) click to toggle source

Used by UserDB to create a basic password entry

# File lib/webrick/httpauth/basicauth.rb, line 42
def self.make_passwd(realm, user, pass)
  pass ||= ""
  pass.crypt(Utils::random_string(2))
end
new(config, default=Config::BasicAuth) click to toggle source

Creates a new BasicAuth instance.

See WEBrick::Config::BasicAuth for default configuration entries

You must supply the following configuration entries:

:Realm

The name of the realm being protected.

:UserDB

A database of usernames and passwords. A WEBrick::HTTPAuth::Htpasswd instance should be used.

# File lib/webrick/httpauth/basicauth.rb, line 60
def initialize(config, default=Config::BasicAuth)
  check_init(config)
  @config = default.dup.update(config)
end

Public Instance Methods

authenticate(req, res) click to toggle source

Authenticates a req and returns a 401 Unauthorized using res if the authentication was not correct.

# File lib/webrick/httpauth/basicauth.rb, line 69
def authenticate(req, res)
  unless basic_credentials = check_scheme(req)
    challenge(req, res)
  end
  userid, password = basic_credentials.unpack("m*")[0].split(":", 2)
  password ||= ""
  if userid.empty?
    error("user id was not given.")
    challenge(req, res)
  end
  unless encpass = @userdb.get_passwd(@realm, userid, @reload_db)
    error("%s: the user is not allowed.", userid)
    challenge(req, res)
  end
  if password.crypt(encpass) != encpass
    error("%s: password unmatch.", userid)
    challenge(req, res)
  end
  info("%s: authentication succeeded.", userid)
  req.user = userid
end
challenge(req, res) click to toggle source

Returns a challenge response which asks for for authentication information

# File lib/webrick/httpauth/basicauth.rb, line 95
def challenge(req, res)
  res[@response_field] = "#{@auth_scheme} realm=\"#{@realm}\""
  raise @auth_exception
end


class WEBrick::HTTPAuth::DigestAuth - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPAuth::DigestAuth

RFC 2617 Digest Access Authentication for WEBrick

Use this class to add digest authentication to a WEBrick servlet.

Here is an example of how to set up DigestAuth:

config = { :Realm => 'DigestAuth example realm' }

htdigest = WEBrick::HTTPAuth::Htdigest.new 'my_password_file'
htdigest.set_passwd config[:Realm], 'username', 'password'
htdigest.flush

config[:UserDB] = htdigest

digest_auth = WEBrick::HTTPAuth::DigestAuth.new config

When using this as with a servlet be sure not to create a new DigestAuth object in the servlet's initialize. By default WEBrick creates a new servlet instance for every request and the DigestAuth object must be used across requests.

In Files

  • lib/webrick/httpauth/digestauth.rb

Parent

Object

Included Modules

  • WEBrick::HTTPAuth::Authenticator

Attributes

algorithm[R]

Digest authentication algorithm

qop[R]

Quality of protection. RFC 2617 defines “auth” and “auth-int”

Public Class Methods

make_passwd(realm, user, pass) click to toggle source

Used by UserDB to create a digest password entry

# File lib/webrick/httpauth/digestauth.rb, line 68
def self.make_passwd(realm, user, pass)
  pass ||= ""
  Digest::MD5::hexdigest([user, realm, pass].join(":"))
end
new(config, default=Config::DigestAuth) click to toggle source

Creates a new DigestAuth instance. Be sure to use the same DigestAuth instance for multiple requests as it saves state between requests in order to perform authentication.

See WEBrick::Config::DigestAuth for default configuration entries

You must supply the following configuration entries:

:Realm

The name of the realm being protected.

:UserDB

A database of usernames and passwords. A WEBrick::HTTPAuth::Htdigest instance should be used.

# File lib/webrick/httpauth/digestauth.rb, line 86
def initialize(config, default=Config::DigestAuth)
  check_init(config)
  @config                 = default.dup.update(config)
  @algorithm              = @config[:Algorithm]
  @domain                 = @config[:Domain]
  @qop                    = @config[:Qop]
  @use_opaque             = @config[:UseOpaque]
  @use_next_nonce         = @config[:UseNextNonce]
  @check_nc               = @config[:CheckNc]
  @use_auth_info_header   = @config[:UseAuthenticationInfoHeader]
  @nonce_expire_period    = @config[:NonceExpirePeriod]
  @nonce_expire_delta     = @config[:NonceExpireDelta]
  @internet_explorer_hack = @config[:InternetExplorerHack]

  case @algorithm
  when 'MD5','MD5-sess'
    @h = Digest::MD5
  when 'SHA1','SHA1-sess'  # it is a bonus feature :-)
    @h = Digest::SHA1
  else
    msg = format('Algorithm "%s" is not supported.', @algorithm)
    raise ArgumentError.new(msg)
  end

  @instance_key = hexdigest(self.__id__, Time.now.to_i, Process.pid)
  @opaques = {}
  @last_nonce_expire = Time.now
  @mutex = Mutex.new
end

Public Instance Methods

authenticate(req, res) click to toggle source

Authenticates a req and returns a 401 Unauthorized using res if the authentication was not correct.

# File lib/webrick/httpauth/digestauth.rb, line 120
def authenticate(req, res)
  unless result = @mutex.synchronize{ _authenticate(req, res) }
    challenge(req, res)
  end
  if result == :nonce_is_stale
    challenge(req, res, true)
  end
  return true
end
challenge(req, res, stale=false) click to toggle source

Returns a challenge response which asks for for authentication information

# File lib/webrick/httpauth/digestauth.rb, line 134
def challenge(req, res, stale=false)
  nonce = generate_next_nonce(req)
  if @use_opaque
    opaque = generate_opaque(req)
    @opaques[opaque].nonce = nonce
  end

  param = Hash.new
  param["realm"]  = HTTPUtils::quote(@realm)
  param["domain"] = HTTPUtils::quote(@domain.to_a.join(" ")) if @domain
  param["nonce"]  = HTTPUtils::quote(nonce)
  param["opaque"] = HTTPUtils::quote(opaque) if opaque
  param["stale"]  = stale.to_s
  param["algorithm"] = @algorithm
  param["qop"]    = HTTPUtils::quote(@qop.to_a.join(",")) if @qop

  res[@response_field] =
    "#{@auth_scheme} " + param.map{|k,v| "#{k}=#{v}" }.join(", ")
  info("%s: %s", @response_field, res[@response_field]) if $DEBUG
  raise @auth_exception
end


class WEBrick::HTTPAuth::Htdigest - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPAuth::Htdigest

Htdigest accesses apache-compatible digest password files. Passwords are matched to a realm where they are valid. For security, the path for a digest password database should be stored outside of the paths available to the HTTP server.

Htdigest is intended for use with WEBrick::HTTPAuth::DigestAuth and stores passwords using cryptographic hashes.

htpasswd = WEBrick::HTTPAuth::Htdigest.new 'my_password_file'
htpasswd.set_passwd 'my realm', 'username', 'password'
htpasswd.flush

In Files

  • lib/webrick/httpauth/htdigest.rb

Parent

Object

Included Modules

  • WEBrick::HTTPAuth::UserDB

Public Class Methods

new(path) click to toggle source

Open a digest password database at path

# File lib/webrick/httpauth/htdigest.rb, line 36
def initialize(path)
  @path = path
  @mtime = Time.at(0)
  @digest = Hash.new
  @mutex = Mutex::new
  @auth_type = DigestAuth
  open(@path,"a").close unless File::exist?(@path)
  reload
end

Public Instance Methods

delete_passwd(realm, user) click to toggle source

Removes a password from the database for user in realm.

# File lib/webrick/httpauth/htdigest.rb, line 109
def delete_passwd(realm, user)
  if hash = @digest[realm]
    hash.delete(user)
  end
end
each() { |user, realm, password_hash| ... } click to toggle source

Iterate passwords in the database.

# File lib/webrick/httpauth/htdigest.rb, line 118
def each # :yields: [user, realm, password_hash]
  @digest.keys.sort.each{|realm|
    hash = @digest[realm]
    hash.keys.sort.each{|user|
      yield([user, realm, hash[user]])
    }
  }
end
flush(output=nil) click to toggle source

Flush the password database. If output is given the database will be written there instead of to the original path.

# File lib/webrick/httpauth/htdigest.rb, line 71
def flush(output=nil)
  output ||= @path
  tmp = Tempfile.new("htpasswd", File::dirname(output))
  begin
    each{|item| tmp.puts(item.join(":")) }
    tmp.close
    File::rename(tmp.path, output)
  rescue
    tmp.close(true)
  end
end
get_passwd(realm, user, reload_db) click to toggle source

Retrieves a password from the database for user in realm. If reload_db is true the database will be reloaded first.

# File lib/webrick/httpauth/htdigest.rb, line 87
def get_passwd(realm, user, reload_db)
  reload() if reload_db
  if hash = @digest[realm]
    hash[user]
  end
end
reload() click to toggle source

Reloads passwords from the database

# File lib/webrick/httpauth/htdigest.rb, line 49
def reload
  mtime = File::mtime(@path)
  if mtime > @mtime
    @digest.clear
    open(@path){|io|
      while line = io.gets
        line.chomp!
        user, realm, pass = line.split(/:/, 3)
        unless @digest[realm]
          @digest[realm] = Hash.new
        end
        @digest[realm][user] = pass
      end
    }
    @mtime = mtime
  end
end
set_passwd(realm, user, pass) click to toggle source

Sets a password in the database for user in realm to pass.

# File lib/webrick/httpauth/htdigest.rb, line 97
def set_passwd(realm, user, pass)
  @mutex.synchronize{
    unless @digest[realm]
      @digest[realm] = Hash.new
    end
    @digest[realm][user] = make_passwd(realm, user, pass)
  }
end


class WEBrick::HTTPAuth::Htgroup - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPAuth::Htgroup

Htgroup accesses apache-compatible group files. Htgroup can be used to provide group-based authentication for users. Currently Htgroup is not directly integrated with any authenticators in WEBrick. For security, the path for a digest password database should be stored outside of the paths available to the HTTP server.

Example:

htgroup = WEBrick::HTTPAuth::Htgroup.new 'my_group_file'
htgroup.add 'superheroes', %w[spiderman batman]

htgroup.members('superheroes').include? 'magneto' # => false

In Files

  • lib/webrick/httpauth/htgroup.rb

Parent

Object

Public Class Methods

new(path) click to toggle source

Open a group database at path

# File lib/webrick/httpauth/htgroup.rb, line 34
def initialize(path)
  @path = path
  @mtime = Time.at(0)
  @group = Hash.new
  open(@path,"a").close unless File::exist?(@path)
  reload
end

Public Instance Methods

add(group, members) click to toggle source

Add an Array of members to group

# File lib/webrick/httpauth/htgroup.rb, line 88
def add(group, members)
  @group[group] = members(group) | members
end
flush(output=nil) click to toggle source

Flush the group database. If output is given the database will be written there instead of to the original path.

# File lib/webrick/httpauth/htgroup.rb, line 63
def flush(output=nil)
  output ||= @path
  tmp = Tempfile.new("htgroup", File::dirname(output))
  begin
    @group.keys.sort.each{|group|
      tmp.puts(format("%s: %s", group, self.members(group).join(" ")))
    }
    tmp.close
    File::rename(tmp.path, output)
  rescue
    tmp.close(true)
  end
end
members(group) click to toggle source

Retrieve the list of members from group

# File lib/webrick/httpauth/htgroup.rb, line 80
def members(group)
  reload
  @group[group] || []
end
reload() click to toggle source

Reload groups from the database

# File lib/webrick/httpauth/htgroup.rb, line 45
def reload
  if (mtime = File::mtime(@path)) > @mtime
    @group.clear
    open(@path){|io|
      while line = io.gets
        line.chomp!
        group, members = line.split(/:\s*/)
        @group[group] = members.split(/\s+/)
      end
    }
    @mtime = mtime
  end
end


class WEBrick::HTTPAuth::Htpasswd - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPAuth::Htpasswd

Htpasswd accesses apache-compatible password files. Passwords are matched to a realm where they are valid. For security, the path for a password database should be stored outside of the paths available to the HTTP server.

Htpasswd is intended for use with WEBrick::HTTPAuth::BasicAuth.

To create an Htpasswd database with a single user:

htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file'
htpasswd.set_passwd 'my realm', 'username', 'password'
htpasswd.flush

In Files

  • lib/webrick/httpauth/htpasswd.rb

Parent

Object

Included Modules

  • WEBrick::HTTPAuth::UserDB

Public Class Methods

new(path) click to toggle source

Open a password database at path

# File lib/webrick/httpauth/htpasswd.rb, line 37
def initialize(path)
  @path = path
  @mtime = Time.at(0)
  @passwd = Hash.new
  @auth_type = BasicAuth
  open(@path,"a").close unless File::exist?(@path)
  reload
end

Public Instance Methods

delete_passwd(realm, user) click to toggle source

Removes a password from the database for user in realm.

# File lib/webrick/httpauth/htpasswd.rb, line 107
def delete_passwd(realm, user)
  @passwd.delete(user)
end
each() { |user, password| ... } click to toggle source

Iterate passwords in the database.

# File lib/webrick/httpauth/htpasswd.rb, line 114
def each # :yields: [user, password]
  @passwd.keys.sort.each{|user|
    yield([user, @passwd[user]])
  }
end
flush(output=nil) click to toggle source

Flush the password database. If output is given the database will be written there instead of to the original path.

# File lib/webrick/httpauth/htpasswd.rb, line 76
def flush(output=nil)
  output ||= @path
  tmp = Tempfile.new("htpasswd", File::dirname(output))
  begin
    each{|item| tmp.puts(item.join(":")) }
    tmp.close
    File::rename(tmp.path, output)
  rescue
    tmp.close(true)
  end
end
get_passwd(realm, user, reload_db) click to toggle source

Retrieves a password from the database for user in realm. If reload_db is true the database will be reloaded first.

# File lib/webrick/httpauth/htpasswd.rb, line 92
def get_passwd(realm, user, reload_db)
  reload() if reload_db
  @passwd[user]
end
reload() click to toggle source

Reload passwords from the database

# File lib/webrick/httpauth/htpasswd.rb, line 49
def reload
  mtime = File::mtime(@path)
  if mtime > @mtime
    @passwd.clear
    open(@path){|io|
      while line = io.gets
        line.chomp!
        case line
        when %r\A[^:]+:[a-zA-Z0-9./]{13}\z!
          user, pass = line.split(":")
        when /:\$/, /:{SHA}/
          raise NotImplementedError,
                'MD5, SHA1 .htpasswd file not supported'
        else
          raise StandardError, 'bad .htpasswd file'
        end
        @passwd[user] = pass
      end
    }
    @mtime = mtime
  end
end
set_passwd(realm, user, pass) click to toggle source

Sets a password in the database for user in realm to pass.

# File lib/webrick/httpauth/htpasswd.rb, line 100
def set_passwd(realm, user, pass)
  @passwd[user] = make_passwd(realm, user, pass)
end


module WEBrick::HTTPAuth::ProxyAuthenticator - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick::HTTPAuth::ProxyAuthenticator

Module providing generic support for both Digest and Basic authentication schemes for proxies.

In Files

  • lib/webrick/httpauth/authenticator.rb


class WEBrick::HTTPAuth::ProxyBasicAuth - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPAuth::ProxyBasicAuth

Basic authentication for proxy servers. See BasicAuth for details.

In Files

  • lib/webrick/httpauth/basicauth.rb

Parent

WEBrick::HTTPAuth::BasicAuth

Included Modules

  • WEBrick::HTTPAuth::ProxyAuthenticator


class WEBrick::HTTPAuth::ProxyDigestAuth - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPAuth::ProxyDigestAuth

Digest authentication for proxy servers. See DigestAuth for details.

In Files

  • lib/webrick/httpauth/digestauth.rb

Parent

WEBrick::HTTPAuth::DigestAuth

Included Modules

  • WEBrick::HTTPAuth::ProxyAuthenticator


module WEBrick::HTTPAuth::UserDB - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick::HTTPAuth::UserDB

User database mixin for HTTPAuth. This mixin dispatches user record access to the underlying #auth_type for this database.

In Files

  • lib/webrick/httpauth/userdb.rb

Attributes

auth_type[RW]

The authentication type.

WEBrick::HTTPAuth::BasicAuth or WEBrick::HTTPAuth::DigestAuth are built-in.

Public Instance Methods

get_passwd(realm, user, reload_db=false) click to toggle source

Retrieves a password in realm for user for the #auth_type of this database. reload_db is a dummy value.

# File lib/webrick/httpauth/userdb.rb, line 47
def get_passwd(realm, user, reload_db=false)
  make_passwd(realm, user, self[user])
end
make_passwd(realm, user, pass) click to toggle source

Creates an obscured password in realm with user and password using the #auth_type of this database.

# File lib/webrick/httpauth/userdb.rb, line 31
def make_passwd(realm, user, pass)
  @auth_type::make_passwd(realm, user, pass)
end
set_passwd(realm, user, pass) click to toggle source

Sets a password in realm with user and password for the #auth_type of this database.

# File lib/webrick/httpauth/userdb.rb, line 39
def set_passwd(realm, user, pass)
  self[user] = pass
end


class WEBrick::HTTPProxyServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPProxyServer

An HTTP Proxy server which proxies GET, HEAD and POST requests.

To create a simple proxy server:

require 'webrick'
require 'webrick/httpproxy'

proxy = WEBrick::HTTPProxyServer.new Port: 8000

trap 'INT'  do proxy.shutdown end
trap 'TERM' do proxy.shutdown end

proxy.start

See ::new for proxy-specific configuration items.

Modifying proxied responses

To modify content the proxy server returns use the :ProxyContentHandler option:

handler = proc do |req, res|
  if res['content-type'] == 'text/plain' then
    res.body << "\nThis content was proxied!\n"
  end
end

proxy =
  WEBrick::HTTPProxyServer.new Port: 8000, ProxyContentHandler: handler

In Files

  • lib/webrick/httpproxy.rb

Parent

HTTPServer

Public Class Methods

new(config={}, default=Config::HTTP) click to toggle source

Proxy server configurations. The proxy server handles the following configuration items in addition to those supported by HTTPServer:

:ProxyAuthProc

Called with a request and response to authorize a request

:ProxyVia

Appended to the via header

:ProxyURI

The proxy server's URI

:ProxyContentHandler

Called with a request and response and allows modification of the response

:ProxyTimeout

Sets the proxy timeouts to 30 seconds for open and 60 seconds for read operations

# File lib/webrick/httpproxy.rb, line 85
def initialize(config={}, default=Config::HTTP)
  super(config, default)
  c = @config
  @via = "#{c[:HTTPVersion]} #{c[:ServerName]}:#{c[:Port]}"
end


class WEBrick::HTTPRequest - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPRequest

An HTTP request. This is consumed by service and do_* methods in WEBrick servlets

In Files

  • lib/webrick/httprequest.rb
  • lib/webrick/https.rb

Parent

Object

Attributes

addr[R]

The socket address of the server

attributes[R]

Hash of request attributes

cipher[R]

HTTP request SSL cipher

client_cert[R]

HTTP request client certificate

keep_alive[R]

Is this a keep-alive connection?

peeraddr[R]

The socket address of the client

request_time[R]

The local time this request was received

server_cert[R]

HTTP request server certificate

user[RW]

The remote user (CGI variable)

Public Class Methods

new(config) click to toggle source

Creates a new HTTP request. WEBrick::Config::HTTP is the default configuration.

# File lib/webrick/httprequest.rb, line 151
def initialize(config)
  @config = config
  @buffer_size = @config[:InputBufferSize]
  @logger = config[:Logger]

  @request_line = @request_method =
    @unparsed_uri = @http_version = nil

  @request_uri = @host = @port = @path = nil
  @script_name = @path_info = nil
  @query_string = nil
  @query = nil
  @form_data = nil

  @raw_header = Array.new
  @header = nil
  @cookies = []
  @accept = []
  @accept_charset = []
  @accept_encoding = []
  @accept_language = []
  @body = ""

  @addr = @peeraddr = nil
  @attributes = {}
  @user = nil
  @keep_alive = false
  @request_time = nil

  @remaining_size = nil
  @socket = nil

  @forwarded_proto = @forwarded_host = @forwarded_port =
    @forwarded_server = @forwarded_for = nil
end

Public Instance Methods

[](header_name) click to toggle source

Retrieves header_name

# File lib/webrick/httprequest.rb, line 286
def [](header_name)
  if @header
    value = @header[header_name.downcase]
    value.empty? ? nil : value.join(", ")
  end
end
body() { |body_chunk| ... } click to toggle source

Returns the request body.

# File lib/webrick/httprequest.rb, line 253
def body(&block) # :yields: body_chunk
  block ||= Proc.new{|chunk| @body << chunk }
  read_body(@socket, block)
  @body.empty? ? nil : @body
end
content_length() click to toggle source

The content-length header

# File lib/webrick/httprequest.rb, line 272
def content_length
  return Integer(self['content-length'])
end
content_type() click to toggle source

The content-type header

# File lib/webrick/httprequest.rb, line 279
def content_type
  return self['content-type']
end
each() { |k, empty? ? nil : join(", ")| ... } click to toggle source

Iterates over the request headers

# File lib/webrick/httprequest.rb, line 296
def each
  if @header
    @header.each{|k, v|
      value = @header[k]
      yield(k, value.empty? ? nil : value.join(", "))
    }
  end
end
host() click to toggle source

The host this request is for

# File lib/webrick/httprequest.rb, line 308
def host
  return @forwarded_host || @host
end
keep_alive?() click to toggle source

Should the connection this request was made on be kept alive?

# File lib/webrick/httprequest.rb, line 343
def keep_alive?
  @keep_alive
end
meta_vars() click to toggle source

This method provides the metavariables defined by the revision 3 of “The WWW Common Gateway Interface Version 1.1” Web.Golux.Com/coar/cgi/

# File lib/webrick/httprequest.rb, line 374
def meta_vars
  meta = Hash.new

  cl = self["Content-Length"]
  ct = self["Content-Type"]
  meta["CONTENT_LENGTH"]    = cl if cl.to_i > 0
  meta["CONTENT_TYPE"]      = ct.dup if ct
  meta["GATEWAY_INTERFACE"] = "CGI/1.1"
  meta["PATH_INFO"]         = @path_info ? @path_info.dup : ""
 #meta["PATH_TRANSLATED"]   = nil      # no plan to be provided
  meta["QUERY_STRING"]      = @query_string ? @query_string.dup : ""
  meta["REMOTE_ADDR"]       = @peeraddr[3]
  meta["REMOTE_HOST"]       = @peeraddr[2]
 #meta["REMOTE_IDENT"]      = nil      # no plan to be provided
  meta["REMOTE_USER"]       = @user
  meta["REQUEST_METHOD"]    = @request_method.dup
  meta["REQUEST_URI"]       = @request_uri.to_s
  meta["SCRIPT_NAME"]       = @script_name.dup
  meta["SERVER_NAME"]       = @host
  meta["SERVER_PORT"]       = @port.to_s
  meta["SERVER_PROTOCOL"]   = "HTTP/" + @config[:HTTPVersion].to_s
  meta["SERVER_SOFTWARE"]   = @config[:ServerSoftware].dup

  self.each{|key, val|
    next if /^content-type$/ =~ key
    next if /^content-length$/ =~ key
    name = "HTTP_" + key
    name.gsub!(/-/, "_")
    name.upcase!
    meta[name] = val
  }

  meta
end
parse(socket=nil) click to toggle source

Parses a request from socket. This is called internally by WEBrick::HTTPServer.

# File lib/webrick/httprequest.rb, line 191
def parse(socket=nil)
  @socket = socket
  begin
    @peeraddr = socket.respond_to?(:peeraddr) ? socket.peeraddr : []
    @addr = socket.respond_to?(:addr) ? socket.addr : []
  rescue Errno::ENOTCONN
    raise HTTPStatus::EOFError
  end

  read_request_line(socket)
  if @http_version.major > 0
    read_header(socket)
    @header['cookie'].each{|cookie|
      @cookies += Cookie::parse(cookie)
    }
    @accept = HTTPUtils.parse_qvalues(self['accept'])
    @accept_charset = HTTPUtils.parse_qvalues(self['accept-charset'])
    @accept_encoding = HTTPUtils.parse_qvalues(self['accept-encoding'])
    @accept_language = HTTPUtils.parse_qvalues(self['accept-language'])
  end
  return if @request_method == "CONNECT"
  return if @unparsed_uri == "*"

  begin
    setup_forwarded_info
    @request_uri = parse_uri(@unparsed_uri)
    @path = HTTPUtils::unescape(@request_uri.path)
    @path = HTTPUtils::normalize_path(@path)
    @host = @request_uri.host
    @port = @request_uri.port
    @query_string = @request_uri.query
    @script_name = ""
    @path_info = @path.dup
  rescue
    raise HTTPStatus::BadRequest, "bad URI `#{@unparsed_uri}'."
  end

  if /close/o =~ self["connection"]
    @keep_alive = false
  elsif /keep-alive/o =~ self["connection"]
    @keep_alive = true
  elsif @http_version < "1.1"
    @keep_alive = false
  else
    @keep_alive = true
  end
end
port() click to toggle source

The port this request is for

# File lib/webrick/httprequest.rb, line 315
def port
  return @forwarded_port || @port
end
query() click to toggle source

Request query as a Hash

# File lib/webrick/httprequest.rb, line 262
def query
  unless @query
    parse_query()
  end
  @query
end
remote_ip() click to toggle source

The client's IP address

# File lib/webrick/httprequest.rb, line 329
def remote_ip
  return self["client-ip"] || @forwarded_for || @peeraddr[3]
end
server_name() click to toggle source

The server name this request is for

# File lib/webrick/httprequest.rb, line 322
def server_name
  return @forwarded_server || @config[:ServerName]
end
ssl?() click to toggle source

Is this an SSL request?

# File lib/webrick/httprequest.rb, line 336
def ssl?
  return @request_uri.scheme == "https"
end

Header and entity body

↑ top

Attributes

accept[R]

The Accept header value

accept_charset[R]

The Accept-Charset header value

accept_encoding[R]

The Accept-Encoding header value

accept_language[R]

The Accept-Language header value

cookies[R]

The parsed request cookies

header[R]

The parsed header of the request

raw_header[R]

The raw header of the request

Request line

↑ top

Attributes

http_version[R]

The HTTP version of the request

request_line[R]

The complete request line such as:

GET / HTTP/1.1
request_method[R]

The request method, GET, POST, PUT, etc.

unparsed_uri[R]

The unparsed URI of the request

Request-URI

↑ top

Attributes

path[R]

The request path

path_info[RW]

The path info (CGI variable)

query_string[RW]

The query from the URI of the request

request_uri[R]

The parsed URI of the request

script_name[RW]

The script name (CGI variable)


class WEBrick::HTTPResponse - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPResponse

An HTTP response. This is filled in by the service or do_* methods of a WEBrick HTTP Servlet.

In Files

  • lib/webrick/httpresponse.rb

Parent

Object

Attributes

body[RW]

Body may be a String or IO subclass.

config[R]

Configuration for this response

cookies[R]

Response cookies

filename[RW]

Filename of the static file in this response. Only used by the FileHandler servlet.

header[R]

Response header

http_version[R]

HTTP Response version

keep_alive[RW]

Is this a keep-alive response?

reason_phrase[RW]

Response reason phrase (“OK”)

request_http_version[RW]

Request HTTP version for this response

request_method[RW]

Request method for this response

request_uri[RW]

Request URI for this response

sent_size[R]

Bytes sent in this response

status[R]

Response status code (200)

Public Class Methods

new(config) click to toggle source

Creates a new HTTP response object. WEBrick::Config::HTTP is the default configuration.

# File lib/webrick/httpresponse.rb, line 94
def initialize(config)
  @config = config
  @buffer_size = config[:OutputBufferSize]
  @logger = config[:Logger]
  @header = Hash.new
  @status = HTTPStatus::RC_OK
  @reason_phrase = nil
  @http_version = HTTPVersion::convert(@config[:HTTPVersion])
  @body = ''
  @keep_alive = true
  @cookies = []
  @request_method = nil
  @request_uri = nil
  @request_http_version = @http_version  # temporary
  @chunked = false
  @filename = nil
  @sent_size = 0
end

Public Instance Methods

[](field) click to toggle source

Retrieves the response header field

# File lib/webrick/httpresponse.rb, line 131
def [](field)
  @header[field.downcase]
end
[]=(field, value) click to toggle source

Sets the response header field to value

# File lib/webrick/httpresponse.rb, line 138
def []=(field, value)
  @header[field.downcase] = value.to_s
end
chunked=(val) click to toggle source

Enables chunked transfer encoding.

# File lib/webrick/httpresponse.rb, line 189
def chunked=(val)
  @chunked = val ? true : false
end
chunked?() click to toggle source

Will this response body be returned using chunked transfer-encoding?

# File lib/webrick/httpresponse.rb, line 182
def chunked?
  @chunked
end
content_length() click to toggle source

The content-length header

# File lib/webrick/httpresponse.rb, line 145
def content_length
  if len = self['content-length']
    return Integer(len)
  end
end
content_length=(len) click to toggle source

Sets the content-length header to len

# File lib/webrick/httpresponse.rb, line 154
def content_length=(len)
  self['content-length'] = len.to_s
end
content_type() click to toggle source

The content-type header

# File lib/webrick/httpresponse.rb, line 161
def content_type
  self['content-type']
end
content_type=(type) click to toggle source

Sets the content-type header to type

# File lib/webrick/httpresponse.rb, line 168
def content_type=(type)
  self['content-type'] = type
end
each() { |field, value| ... } click to toggle source

Iterates over each header in the resopnse

# File lib/webrick/httpresponse.rb, line 175
def each
  @header.each{|field, value|  yield(field, value) }
end
keep_alive?() click to toggle source

Will this response's connection be kept alive?

# File lib/webrick/httpresponse.rb, line 196
def keep_alive?
  @keep_alive
end
set_error(ex, backtrace=false) click to toggle source

Creates an error page for exception ex with an optional backtrace

# File lib/webrick/httpresponse.rb, line 330
    def set_error(ex, backtrace=false)
      case ex
      when HTTPStatus::Status
        @keep_alive = false if HTTPStatus::error?(ex.code)
        self.status = ex.code
      else
        @keep_alive = false
        self.status = HTTPStatus::RC_INTERNAL_SERVER_ERROR
      end
      @header['content-type'] = "text/html; charset=ISO-8859-1"

      if respond_to?(:create_error_page)
        create_error_page()
        return
      end

      if @request_uri
        host, port = @request_uri.host, @request_uri.port
      else
        host, port = @config[:ServerName], @config[:Port]
      end

      @body = ''
      @body << <<-_end_of_html_
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
  <HEAD><TITLE>#{HTMLUtils::escape(@reason_phrase)}</TITLE></HEAD>
  <BODY>
    <H1>#{HTMLUtils::escape(@reason_phrase)}</H1>
    #{HTMLUtils::escape(ex.message)}
    <HR>
      _end_of_html_

      if backtrace && $DEBUG
        @body << "backtrace of `#{HTMLUtils::escape(ex.class.to_s)}' "
        @body << "#{HTMLUtils::escape(ex.message)}"
        @body << "<PRE>"
        ex.backtrace.each{|line| @body << "\t#{line}\n"}
        @body << "</PRE><HR>"
      end

      @body << <<-_end_of_html_
    <ADDRESS>
     #{HTMLUtils::escape(@config[:ServerSoftware])} at
     #{host}:#{port}
    </ADDRESS>
  </BODY>
</HTML>
      _end_of_html_
    end
set_redirect(status, url) click to toggle source

Redirects to url with a WEBrick::HTTPStatus::Redirect status.

Example:

res.set_redirect WEBrick::HTTPStatus::TemporaryRedirect
# File lib/webrick/httpresponse.rb, line 321
def set_redirect(status, url)
  @body = "<HTML><A HREF=\"#{url.to_s}\">#{url.to_s}</A>.</HTML>\n"
  @header['location'] = url.to_s
  raise status
end
status=(status) click to toggle source

Sets the response's status to the status code

# File lib/webrick/httpresponse.rb, line 123
def status=(status)
  @status = status
  @reason_phrase = HTTPStatus::reason_phrase(status)
end
status_line() click to toggle source

The response's HTTP status line

# File lib/webrick/httpresponse.rb, line 116
def status_line
  "HTTP/#@http_version #@status #@reason_phrase #{CRLF}"
end


class WEBrick::HTTPServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPServer

An HTTP Server

In Files

  • lib/webrick/httpserver.rb

Parent

WEBrick::GenericServer

Public Class Methods

new(config={}, default=Config::HTTP) click to toggle source

Creates a new HTTP server according to config

An HTTP server uses the following attributes:

:AccessLog

An array of access logs. See WEBrick::AccessLog

:BindAddress

Local address for the server to bind to

:DocumentRoot

Root path to serve files from

:DocumentRootOptions

Options for the default HTTPServlet::FileHandler

:HTTPVersion

The HTTP version of this server

:Port

Port to listen on

:RequestCallback

Called with a request and response before each request is serviced.

:RequestTimeout

Maximum time to wait between requests

:ServerAlias

Array of alternate names for this server for virtual hosting

:ServerName

Name for this server for virtual hosting

# File lib/webrick/httpserver.rb, line 44
def initialize(config={}, default=Config::HTTP)
  super(config, default)
  @http_version = HTTPVersion::convert(@config[:HTTPVersion])

  @mount_tab = MountTable.new
  if @config[:DocumentRoot]
    mount("/", HTTPServlet::FileHandler, @config[:DocumentRoot],
          @config[:DocumentRootOptions])
  end

  unless @config[:AccessLog]
    @config[:AccessLog] = [
      [ $stderr, AccessLog::COMMON_LOG_FORMAT ],
      [ $stderr, AccessLog::REFERER_LOG_FORMAT ]
    ]
  end

  @virtual_hosts = Array.new
end

Public Instance Methods

access_log(config, req, res) click to toggle source

Logs req and res in the access logs. config is used for the server name.

# File lib/webrick/httpserver.rb, line 218
def access_log(config, req, res)
  param = AccessLog::setup_params(config, req, res)
  @config[:AccessLog].each{|logger, fmt|
    logger << AccessLog::format(fmt+"\n", param)
  }
end
do_OPTIONS(req, res) click to toggle source

The default OPTIONS request handler says GET, HEAD, POST and OPTIONS requests are allowed.

# File lib/webrick/httpserver.rb, line 145
def do_OPTIONS(req, res)
  res["allow"] = "GET,HEAD,POST,OPTIONS"
end
lookup_server(req) click to toggle source

Finds the appropriate virtual host to handle req

# File lib/webrick/httpserver.rb, line 205
def lookup_server(req)
  @virtual_hosts.find{|s|
    (s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) &&
    (s[:Port].nil?        || req.port == s[:Port])           &&
    ((s[:ServerName].nil?  || req.host == s[:ServerName]) ||
     (!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host}))
  }
end
mount(dir, servlet, *options) click to toggle source

Mounts servlet on dir passing options to the servlet at creation time

# File lib/webrick/httpserver.rb, line 153
def mount(dir, servlet, *options)
  @logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir))
  @mount_tab[dir] = [ servlet, options ]
end
mount_proc(dir, proc=nil, &block) click to toggle source

Mounts proc or block on dir and calls it with a WEBrick::HTTPRequest and WEBrick::HTTPResponse

# File lib/webrick/httpserver.rb, line 162
def mount_proc(dir, proc=nil, &block)
  proc ||= block
  raise HTTPServerError, "must pass a proc or block" unless proc
  mount(dir, HTTPServlet::ProcHandler.new(proc))
end
run(sock) click to toggle source

Processes requests on sock

# File lib/webrick/httpserver.rb, line 67
def run(sock)
  while true
    res = HTTPResponse.new(@config)
    req = HTTPRequest.new(@config)
    server = self
    begin
      timeout = @config[:RequestTimeout]
      while timeout > 0
        break if IO.select([sock], nil, nil, 0.5)
        timeout = 0 if @status != :Running
        timeout -= 0.5
      end
      raise HTTPStatus::EOFError if timeout <= 0
      raise HTTPStatus::EOFError if sock.eof?
      req.parse(sock)
      res.request_method = req.request_method
      res.request_uri = req.request_uri
      res.request_http_version = req.http_version
      res.keep_alive = req.keep_alive?
      server = lookup_server(req) || self
      if callback = server[:RequestCallback]
        callback.call(req, res)
      elsif callback = server[:RequestHandler]
        msg = ":RequestHandler is deprecated, please use :RequestCallback"
        @logger.warn(msg)
        callback.call(req, res)
      end
      server.service(req, res)
    rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
      res.set_error(ex)
    rescue HTTPStatus::Error => ex
      @logger.error(ex.message)
      res.set_error(ex)
    rescue HTTPStatus::Status => ex
      res.status = ex.code
    rescue StandardError => ex
      @logger.error(ex)
      res.set_error(ex, true)
    ensure
      if req.request_line
        if req.keep_alive? && res.keep_alive?
          req.fixup()
        end
        res.send_response(sock)
        server.access_log(@config, req, res)
      end
    end
    break if @http_version < "1.1"
    break unless req.keep_alive?
    break unless res.keep_alive?
  end
end
search_servlet(path) click to toggle source

Finds a servlet for path

# File lib/webrick/httpserver.rb, line 180
def search_servlet(path)
  script_name, path_info = @mount_tab.scan(path)
  servlet, options = @mount_tab[script_name]
  if servlet
    [ servlet, options, script_name, path_info ]
  end
end
service(req, res) click to toggle source

Services req and fills in res

# File lib/webrick/httpserver.rb, line 123
def service(req, res)
  if req.unparsed_uri == "*"
    if req.request_method == "OPTIONS"
      do_OPTIONS(req, res)
      raise HTTPStatus::OK
    end
    raise HTTPStatus::NotFound, "`#{req.unparsed_uri}' not found."
  end

  servlet, options, script_name, path_info = search_servlet(req.path)
  raise HTTPStatus::NotFound, "`#{req.path}' not found." unless servlet
  req.script_name = script_name
  req.path_info = path_info
  si = servlet.get_instance(self, *options)
  @logger.debug(format("%s is invoked.", si.class.name))
  si.service(req, res)
end
umount(dir) click to toggle source
Alias for: unmount
unmount(dir) click to toggle source

Unmounts dir

# File lib/webrick/httpserver.rb, line 171
def unmount(dir)
  @logger.debug(sprintf("unmount %s.", dir))
  @mount_tab.delete(dir)
end
Also aliased as: umount
virtual_host(server) click to toggle source

Adds server as a virtual host.

# File lib/webrick/httpserver.rb, line 191
def virtual_host(server)
  @virtual_hosts << server
  @virtual_hosts = @virtual_hosts.sort_by{|s|
    num = 0
    num -= 4 if s[:BindAddress]
    num -= 2 if s[:Port]
    num -= 1 if s[:ServerName]
    num
  }
end


class WEBrick::HTTPServerError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPServerError

In Files

  • lib/webrick/httpserver.rb

Parent

ServerError


module WEBrick::HTTPServlet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick::HTTPServlet

In Files

  • lib/webrick/httpservlet/abstract.rb
  • lib/webrick/httpservlet/cgihandler.rb
  • lib/webrick/httpservlet/erbhandler.rb
  • lib/webrick/httpservlet/filehandler.rb
  • lib/webrick/httpservlet/prochandler.rb
  • lib/webrick/httpservlet.rb


class WEBrick::HTTPServlet::AbstractServlet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPServlet::AbstractServlet

AbstractServlet allows HTTP server modules to be reused across multiple servers and allows encapsulation of functionality.

By default a servlet will respond to GET, HEAD (through an alias to GET) and OPTIONS requests.

By default a new servlet is initialized for every request. A servlet instance can be reused by overriding ::get_instance in the AbstractServlet subclass.

A Simple Servlet

class Simple < WEBrick::HTTPServlet::AbstractServlet
  def do_GET request, response
    status, content_type, body = do_stuff_with request

    response.status = status
    response['Content-Type'] = content_type
    response.body = body
  end

  def do_stuff_with request
    return 200, 'text/plain', 'you got a page'
  end
end

This servlet can be mounted on a server at a given path:

server.mount '/simple', Simple

Servlet Configuration

Servlets can be configured via initialize. The first argument is the HTTP server the servlet is being initialized for.

class Configurable < Simple
  def initialize server, color, size
    super server
    @color = color
    @size = size
  end

  def do_stuff_with request
    content = "<p "                %q{style="color: #{@color}; font-size: #{@size}"}                ">Hello, World!"

    return 200, "text/html", content
  end
end

This servlet must be provided two arguments at mount time:

server.mount '/configurable', Configurable, 'red', '2em'

In Files

  • lib/webrick/httpservlet/abstract.rb

Parent

Object

Public Class Methods

get_instance(server, *options) click to toggle source

Factory for servlet instances that will handle a request from server using options from the mount point. By default a new servlet instance is created for every call.

# File lib/webrick/httpservlet/abstract.rb, line 84
def self.get_instance(server, *options)
  self.new(server, *options)
end
new(server, *options) click to toggle source

Initializes a new servlet for server using options which are stored as-is in +@options+. +@logger+ is also provided.

# File lib/webrick/httpservlet/abstract.rb, line 92
def initialize(server, *options)
  @server = @config = server
  @logger = @server[:Logger]
  @options = options
end

Public Instance Methods

do_GET(req, res) click to toggle source

Raises a NotFound exception

# File lib/webrick/httpservlet/abstract.rb, line 116
def do_GET(req, res)
  raise HTTPStatus::NotFound, "not found."
end
do_HEAD(req, res) click to toggle source

Dispatches to #do_GET

# File lib/webrick/httpservlet/abstract.rb, line 123
def do_HEAD(req, res)
  do_GET(req, res)
end
do_OPTIONS(req, res) click to toggle source

Returns the allowed HTTP request methods

# File lib/webrick/httpservlet/abstract.rb, line 130
def do_OPTIONS(req, res)
  m = self.methods.grep(/\Ado_([A-Z]+)\z/) {$1}
  m.sort!
  res["allow"] = m.join(",")
end
service(req, res) click to toggle source

Dispatches to a do_ method based on req if such a method is available. (do_GET for a GET request). Raises a MethodNotAllowed exception if the method is not implemented.

# File lib/webrick/httpservlet/abstract.rb, line 103
def service(req, res)
  method_name = "do_" + req.request_method.gsub(/-/, "_")
  if respond_to?(method_name)
    __send__(method_name, req, res)
  else
    raise HTTPStatus::MethodNotAllowed,
          "unsupported method `#{req.request_method}'."
  end
end


class WEBrick::HTTPServlet::CGIHandler - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPServlet::CGIHandler

Servlet for handling CGI scripts

Example:

server.mount('/cgi/my_script', WEBrick::HTTPServlet::CGIHandler,
             '/path/to/my_script')

In Files

  • lib/webrick/httpservlet/cgihandler.rb

Parent

WEBrick::HTTPServlet::AbstractServlet

Public Class Methods

new(server, name) click to toggle source

Creates a new CGI script servlet for the script at name

# File lib/webrick/httpservlet/cgihandler.rb, line 34
def initialize(server, name)
  super(server, name)
  @script_filename = name
  @tempdir = server[:TempDir]
  @cgicmd = "#{CGIRunner} #{server[:CGIInterpreter]}"
end


class WEBrick::HTTPServlet::DefaultFileHandler - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPServlet::DefaultFileHandler

Servlet for serving a single file. You probably want to use the FileHandler servlet instead as it handles directories and fancy indexes.

Example:

server.mount('/my_page.txt', WEBrick::HTTPServlet::DefaultFileHandler,
             '/path/to/my_page.txt')

This servlet handles If-Modified-Since and Range requests.

In Files

  • lib/webrick/httpservlet/filehandler.rb

Parent

WEBrick::HTTPServlet::AbstractServlet

Public Class Methods

new(server, local_path) click to toggle source

Creates a DefaultFileHandler instance for the file at local_path.

# File lib/webrick/httpservlet/filehandler.rb, line 37
def initialize(server, local_path)
  super(server, local_path)
  @local_path = local_path
end


class WEBrick::HTTPServlet::ERBHandler - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPServlet::ERBHandler

ERBHandler evaluates an ERB file and returns the result. This handler is automatically used if there are .rhtml files in a directory served by the FileHandler.

ERBHandler supports GET and POST methods.

The ERB file is evaluated with the local variables servlet_request and servlet_response which are a WEBrick::HTTPRequest and WEBrick::HTTPResponse respectively.

Example .rhtml file:

Request to <%= servlet_request.request_uri %>

Query params <%= servlet_request.query.inspect %>

In Files

  • lib/webrick/httpservlet/erbhandler.rb

Parent

WEBrick::HTTPServlet::AbstractServlet

Public Class Methods

new(server, name) click to toggle source

Creates a new ERBHandler on server that will evaluate and serve the ERB file name

# File lib/webrick/httpservlet/erbhandler.rb, line 41
def initialize(server, name)
  super(server, name)
  @script_filename = name
end

Public Instance Methods

do_GET(req, res) click to toggle source

Handles GET requests

# File lib/webrick/httpservlet/erbhandler.rb, line 49
def do_GET(req, res)
  unless defined?(ERB)
    @logger.warn "#{self.class}: ERB not defined."
    raise HTTPStatus::Forbidden, "ERBHandler cannot work."
  end
  begin
    data = open(@script_filename){|io| io.read }
    res.body = evaluate(ERB.new(data), req, res)
    res['content-type'] ||=
      HTTPUtils::mime_type(@script_filename, @config[:MimeTypes])
  rescue StandardError => ex
    raise
  rescue Exception => ex
    @logger.error(ex)
    raise HTTPStatus::InternalServerError, ex.message
  end
end
Also aliased as: do_POST
do_POST(req, res) click to toggle source

Handles POST requests

Alias for: do_GET


class WEBrick::HTTPServlet::FileHandler - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPServlet::FileHandler

Serves a directory including fancy indexing and a variety of other options.

Example:

server.mount '/assets', WEBrick::FileHandler, '/path/to/assets'

In Files

  • lib/webrick/httpservlet/filehandler.rb

Parent

WEBrick::HTTPServlet::AbstractServlet

Public Class Methods

add_handler(suffix, handler) click to toggle source

Allow custom handling of requests for files with suffix by class handler

# File lib/webrick/httpservlet/filehandler.rb, line 162
def self.add_handler(suffix, handler)
  HandlerTable[suffix] = handler
end
new(server, root, options={}, default=Config::FileHandler) click to toggle source

Creates a FileHandler servlet on server that serves files starting at directory root

options may be a Hash containing keys from WEBrick::Config::FileHandler or true or false.

If options is true or false then :FancyIndexing is enabled or disabled respectively.

# File lib/webrick/httpservlet/filehandler.rb, line 183
def initialize(server, root, options={}, default=Config::FileHandler)
  @config = server.config
  @logger = @config[:Logger]
  @root = File.expand_path(root)
  if options == true || options == false
    options = { :FancyIndexing => options }
  end
  @options = default.dup.update(options)
end
remove_handler(suffix) click to toggle source

Remove custom handling of requests for files with suffix

# File lib/webrick/httpservlet/filehandler.rb, line 169
def self.remove_handler(suffix)
  HandlerTable.delete(suffix)
end


class WEBrick::HTTPServlet::HTTPServletError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPServlet::HTTPServletError

In Files

  • lib/webrick/httpservlet/abstract.rb

Parent

StandardError


class WEBrick::HTTPServlet::ProcHandler - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPServlet::ProcHandler

Mounts a proc at a path that accepts a request and response.

Instead of mounting this servlet with WEBrick::HTTPServer#mount use WEBrick::HTTPServer#mount_proc:

server.mount_proc '/' do |req, res|
  res.body = 'it worked!'
  res.status = 200
end

In Files

  • lib/webrick/httpservlet/prochandler.rb

Parent

WEBrick::HTTPServlet::AbstractServlet


module WEBrick::HTTPStatus - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick::HTTPStatus

This module is used to manager HTTP status codes.

See www.w3.org/Protocols/rfc2616/rfc2616-sec10.html for more information.

In Files

  • lib/webrick/httpstatus.rb

Public Class Methods

[](code) click to toggle source

Returns the status class corresponding to code

WEBrick::HTTPStatus[302]
=> WEBrick::HTTPStatus::NotFound

# File lib/webrick/httpstatus.rb, line 186
def self.[](code)
  CodeToError[code]
end
client_error?(code) click to toggle source

Is code a client error status?

# File lib/webrick/httpstatus.rb, line 170
def client_error?(code)
  code.to_i >= 400 and code.to_i < 500
end
error?(code) click to toggle source

Is code an error status?

# File lib/webrick/httpstatus.rb, line 164
def error?(code)
  code.to_i >= 400 and code.to_i < 600
end
info?(code) click to toggle source

Is code an informational status?

# File lib/webrick/httpstatus.rb, line 146
def info?(code)
  code.to_i >= 100 and code.to_i < 200
end
reason_phrase(code) click to toggle source

Returns the description corresponding to the HTTP status code

WEBrick::HTTPStatus.reason_phrase 404
=> "Not Found"

# File lib/webrick/httpstatus.rb, line 140
def reason_phrase(code)
  StatusMessage[code.to_i]
end
redirect?(code) click to toggle source

Is code a redirection status?

# File lib/webrick/httpstatus.rb, line 158
def redirect?(code)
  code.to_i >= 300 and code.to_i < 400
end
server_error?(code) click to toggle source

Is code a server error status?

# File lib/webrick/httpstatus.rb, line 176
def server_error?(code)
  code.to_i >= 500 and code.to_i < 600
end
success?(code) click to toggle source

Is code a successful status?

# File lib/webrick/httpstatus.rb, line 152
def success?(code)
  code.to_i >= 200 and code.to_i < 300
end


class WEBrick::HTTPStatus::ClientError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPStatus::ClientError

Root of the HTTP client error statuses

In Files

  • lib/webrick/httpstatus.rb

Parent

WEBrick::HTTPStatus::Error


class WEBrick::HTTPStatus::EOFError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPStatus::EOFError

In Files

  • lib/webrick/httpstatus.rb

Parent

StandardError


class WEBrick::HTTPStatus::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPStatus::Error

Root of the HTTP error statuses

In Files

  • lib/webrick/httpstatus.rb

Parent

WEBrick::HTTPStatus::Status


class WEBrick::HTTPStatus::Info - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPStatus::Info

Root of the HTTP info statuses

In Files

  • lib/webrick/httpstatus.rb

Parent

WEBrick::HTTPStatus::Status


class WEBrick::HTTPStatus::Redirect - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPStatus::Redirect

Root of the HTTP redirect statuses

In Files

  • lib/webrick/httpstatus.rb

Parent

WEBrick::HTTPStatus::Status


class WEBrick::HTTPStatus::ServerError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPStatus::ServerError

Root of the HTTP server error statuses

In Files

  • lib/webrick/httpstatus.rb

Parent

WEBrick::HTTPStatus::Error


class WEBrick::HTTPStatus::Status - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPStatus::Status

Root of the HTTP status class hierarchy

In Files

  • lib/webrick/httpstatus.rb

Parent

StandardError

Public Instance Methods

code() click to toggle source

Returns the HTTP status code

# File lib/webrick/httpstatus.rb, line 32
def code() self::class::code end
Also aliased as: to_i
reason_phrase() click to toggle source

Returns the HTTP status description

# File lib/webrick/httpstatus.rb, line 35
def reason_phrase() self::class::reason_phrase end
to_i() click to toggle source
Alias for: code


class WEBrick::HTTPStatus::Success - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPStatus::Success

Root of the HTTP sucess statuses

In Files

  • lib/webrick/httpstatus.rb

Parent

WEBrick::HTTPStatus::Status


module WEBrick::HTTPUtils - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick::HTTPUtils

HTTPUtils provides utility methods for working with the HTTP protocol.

This module is generally used internally by WEBrick

In Files

  • lib/webrick/httputils.rb

Constants

DefaultMimeTypes

Default mime types

Public Class Methods

dequote(str) click to toggle source

Removes quotes and escapes from str

# File lib/webrick/httputils.rb, line 220
def dequote(str)
  ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
  ret.gsub!(/\(.)/, "\\1")
  ret
end
load_mime_types(file) click to toggle source

Loads Apache-compatible mime.types in file.

# File lib/webrick/httputils.rb, line 108
def load_mime_types(file)
  open(file){ |io|
    hash = Hash.new
    io.each{ |line|
      next if /^#/ =~ line
      line.chomp!
      mimetype, ext0 = line.split(/\s+/, 2)
      next unless ext0
      next if ext0.empty?
      ext0.split(/\s+/).each{ |ext| hash[ext] = mimetype }
    }
    hash
  }
end
mime_type(filename, mime_tab) click to toggle source

Returns the mime type of filename from the list in mime_tab. If no mime type was found application/octet-stream is returned.

# File lib/webrick/httputils.rb, line 128
def mime_type(filename, mime_tab)
  suffix1 = (/\.(\w+)$/ =~ filename && $1.downcase)
  suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ filename && $1.downcase)
  mime_tab[suffix1] || mime_tab[suffix2] || "application/octet-stream"
end
normalize_path(path) click to toggle source

Normalizes a request path. Raises an exception if the path cannot be normalized.

# File lib/webrick/httputils.rb, line 30
def normalize_path(path)
  raise "abnormal path `#{path}'" if path[0] != /
  ret = path.dup

  ret.gsub!(%r{/+}, '/')                    # //      => /
  while ret.sub!(%r/\.(?:/|\Z)', '/'); end  # /.      => /
  while ret.sub!(%r/(?!\.\./)[^/]+/\.\.(?:/|\Z)', '/'); end # /foo/.. => /foo

  raise "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret
  ret
end
parse_form_data(io, boundary) click to toggle source

Parses form data in io with the given boundary

# File lib/webrick/httputils.rb, line 392
def parse_form_data(io, boundary)
  boundary_regexp = /\A--#{Regexp.quote(boundary)}(--)?#{CRLF}\z/
  form_data = Hash.new
  return form_data unless io
  data = nil
  io.each_line{|line|
    if boundary_regexp =~ line
      if data
        data.chop!
        key = data.name
        if form_data.has_key?(key)
          form_data[key].append_data(data)
        else
          form_data[key] = data
        end
      end
      data = FormData.new
      next
    else
      if data
        data << line
      end
    end
  }
  return form_data
end
parse_header(raw) click to toggle source

Parses an HTTP header raw into a hash of header fields with an Array of values.

# File lib/webrick/httputils.rb, line 139
def parse_header(raw)
  header = Hash.new([].freeze)
  field = nil
  raw.each_line{|line|
    case line
    when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):\s*(.*?)\s*\z/m
      field, value = $1, $2
      field.downcase!
      header[field] = [] unless header.has_key?(field)
      header[field] << value
    when /^\s+(.*?)\s*\z/m
      value = $1
      unless field
        raise HTTPStatus::BadRequest, "bad header '#{line}'."
      end
      header[field][-1] << " " << value
    else
      raise HTTPStatus::BadRequest, "bad header '#{line}'."
    end
  }
  header.each{|key, values|
    values.each{|value|
      value.strip!
      value.gsub!(/\s+/, " ")
    }
  }
  header
end
parse_query(str) click to toggle source

Parses the query component of a URI in str

# File lib/webrick/httputils.rb, line 368
def parse_query(str)
  query = Hash.new
  if str
    str.split(/[&;]/).each{|x|
      next if x.empty?
      key, val = x.split(/=/,2)
      key = unescape_form(key)
      val = unescape_form(val.to_s)
      val = FormData.new(val)
      val.name = key
      if query.has_key?(key)
        query[key].append_data(val)
        next
      end
      query[key] = val
    }
  end
  query
end
parse_qvalues(value) click to toggle source

Parses q values in value as used in Accept headers.

# File lib/webrick/httputils.rb, line 199
def parse_qvalues(value)
  tmp = []
  if value
    parts = value.split(/,\s*/)
    parts.each {|part|
      if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
        val = m[1]
        q = (m[2] or 1).to_f
        tmp.push([val, q])
      end
    }
    tmp = tmp.sort_by{|val, q| -q}
    tmp.collect!{|val, q| val}
  end
  return tmp
end
parse_range_header(ranges_specifier) click to toggle source

Parses a Range header value ranges_specifier

# File lib/webrick/httputils.rb, line 181
def parse_range_header(ranges_specifier)
  if /^bytes=(.*)/ =~ ranges_specifier
    byte_range_set = split_header_value($1)
    byte_range_set.collect{|range_spec|
      case range_spec
      when /^(\d+)-(\d+)/ then $1.to_i .. $2.to_i
      when /^(\d+)-/      then $1.to_i .. -1
      when /^-(\d+)/      then -($1.to_i) .. -1
      else return nil
      end
    }
  end
end
quote(str) click to toggle source

Quotes and escapes quotes in str

# File lib/webrick/httputils.rb, line 230
def quote(str)
  '"' << str.gsub(/[\\"]/, "\\\11"") << '"'
end
split_header_value(str) click to toggle source

Splits a header value str according to HTTP specification.

# File lib/webrick/httputils.rb, line 172
def split_header_value(str)
  str.scan(%r\G((?:"(?:\.|[^"])+?"|[^",]+)+)
                (?:,\s*|\Z)'n).flatten
end

Public Instance Methods

escape(str) click to toggle source

Escapes HTTP reserved and unwise characters in str

# File lib/webrick/httputils.rb, line 464
def escape(str)
  _escape(str, UNESCAPED)
end
escape8bit(str) click to toggle source

Escapes 8 bit characters in str

# File lib/webrick/httputils.rb, line 505
def escape8bit(str)
  _escape(str, NONASCII)
end
escape_form(str) click to toggle source

Escapes form reserved characters in str

# File lib/webrick/httputils.rb, line 478
def escape_form(str)
  ret = _escape(str, UNESCAPED_FORM)
  ret.gsub!(/ /, "+")
  ret
end
escape_path(str) click to toggle source

Escapes path str

# File lib/webrick/httputils.rb, line 494
def escape_path(str)
  result = ""
  str.scan(%r{/([^/]*)}).each{|i|
    result << "/" << _escape(i[0], UNESCAPED_PCHAR)
  }
  return result
end
unescape(str) click to toggle source

Unescapes HTTP reserved and unwise characters in str

# File lib/webrick/httputils.rb, line 471
def unescape(str)
  _unescape(str, ESCAPED)
end
unescape_form(str) click to toggle source

Unescapes form reserved characters in str

# File lib/webrick/httputils.rb, line 487
def unescape_form(str)
  _unescape(str.gsub(/\+/, " "), ESCAPED)
end


class WEBrick::HTTPUtils::FormData - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPUtils::FormData

Stores multipart form data. FormData objects are created when WEBrick::HTTPUtils.parse_form_data is called.

In Files

  • lib/webrick/httputils.rb

Parent

String

Attributes

filename[RW]

The filename of the form data part

name[RW]

The name of the form data part

Public Class Methods

new(*args) click to toggle source

Creates a new FormData object.

args is an Array of form data entries. One FormData will be created for each entry.

This is called by WEBrick::HTTPUtils.parse_form_data for you

# File lib/webrick/httputils.rb, line 264
def initialize(*args)
  @name = @filename = @next_data = nil
  if args.empty?
    @raw_header = []
    @header = nil
    super("")
  else
    @raw_header = EmptyRawHeader
    @header = EmptyHeader
    super(args.shift)
    unless args.empty?
      @next_data = self.class.new(*args)
    end
  end
end

Public Instance Methods

<<(str) click to toggle source

Adds str to this FormData which may be the body, a header or a header entry.

This is called by WEBrick::HTTPUtils.parse_form_data for you

# File lib/webrick/httputils.rb, line 297
def <<(str)
  if @header
    super
  elsif str == CRLF
    @header = HTTPUtils::parse_header(@raw_header.join)
    if cd = self['content-disposition']
      if /\s+name="(.*?)"/ =~ cd then @name = $1 end
      if /\s+filename="(.*?)"/ =~ cd then @filename = $1 end
    end
  else
    @raw_header << str
  end
  self
end
[](*key) click to toggle source

Retrieves the header at the first entry in key

# File lib/webrick/httputils.rb, line 283
def [](*key)
  begin
    @header[key[0].downcase].join(", ")
  rescue StandardError, NameError
    super
  end
end
append_data(data) click to toggle source

Adds data at the end of the chain of entries

This is called by WEBrick::HTTPUtils.parse_form_data for you.

# File lib/webrick/httputils.rb, line 317
def append_data(data)
  tmp = self
  while tmp
    unless tmp.next_data
      tmp.next_data = data
      break
    end
    tmp = tmp.next_data
  end
  self
end
each_data() { |tmp| ... } click to toggle source

Yields each entry in this FormData

# File lib/webrick/httputils.rb, line 332
def each_data
  tmp = self
  while tmp
    next_data = tmp.next_data
    yield(tmp)
    tmp = next_data
  end
end
list() click to toggle source

Returns all the FormData as an Array

# File lib/webrick/httputils.rb, line 344
def list
  ret = []
  each_data{|data|
    ret << data.to_s
  }
  ret
end
Also aliased as: to_ary
to_ary() click to toggle source

A FormData will behave like an Array

Alias for: list
to_s() click to toggle source

This FormData's body

# File lib/webrick/httputils.rb, line 360
def to_s
  String.new(self)
end


class WEBrick::HTTPVersion - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::HTTPVersion

Represents an HTTP protocol version

In Files

  • lib/webrick/httpversion.rb

Parent

Object

Included Modules

  • Comparable

Attributes

major[RW]

The major protocol version number

minor[RW]

The minor protocol version number

Public Class Methods

convert(version) click to toggle source

Converts version into an HTTPVersion

# File lib/webrick/httpversion.rb, line 31
def self.convert(version)
  version.is_a?(self) ? version : new(version)
end
new(version) click to toggle source

Creates a new HTTPVersion from version.

# File lib/webrick/httpversion.rb, line 38
def initialize(version)
  case version
  when HTTPVersion
    @major, @minor = version.major, version.minor
  when String
    if /^(\d+)\.(\d+)$/ =~ version
      @major, @minor = $1.to_i, $2.to_i
    end
  end
  if @major.nil? || @minor.nil?
    raise ArgumentError,
      format("cannot convert %s into %s", version.class, self.class)
  end
end

Public Instance Methods

<=>(other) click to toggle source

Compares this version with other according to the HTTP specification rules.

# File lib/webrick/httpversion.rb, line 57
def <=>(other)
  unless other.is_a?(self.class)
    other = self.class.new(other)
  end
  if (ret = @major <=> other.major) == 0
    return @minor <=> other.minor
  end
  return ret
end
to_s() click to toggle source

The HTTP version as show in the HTTP request and response. For example, “1.1”

# File lib/webrick/httpversion.rb, line 71
def to_s
  format("%d.%d", @major, @minor)
end


class WEBrick::Log - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::Log

A logging class that prepends a timestamp to each message.

In Files

  • lib/webrick/log.rb

Parent

WEBrick::BasicLog

Attributes

time_format[RW]

Format of the timestamp which is applied to each logged line. The default is "[%Y-%m-%d %H:%M:%S]"

Public Class Methods

new(log_file=nil, level=nil) click to toggle source

Same as BasicLog#initialize

You can set the timestamp format through time_format

# File lib/webrick/log.rb, line 142
def initialize(log_file=nil, level=nil)
  super(log_file, level)
  @time_format = "[%Y-%m-%d %H:%M:%S]"
end

Public Instance Methods

log(level, data) click to toggle source

Same as WEBrick::BasicLog#log

# File lib/webrick/log.rb, line 149
def log(level, data)
  tmp = Time.now.strftime(@time_format)
  tmp << " " << data
  super(level, tmp)
end


class WEBrick::ServerError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::ServerError

Server error exception

In Files

  • lib/webrick/server.rb

Parent

StandardError


class WEBrick::SimpleServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::SimpleServer

Base server class

In Files

  • lib/webrick/server.rb

Parent

Object

Public Class Methods

start() { || ... } click to toggle source

A SimpleServer only yields when you start it

# File lib/webrick/server.rb, line 31
def SimpleServer.start
  yield
end


module WEBrick::Utils - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WEBrick::Utils

In Files

  • lib/webrick/ssl.rb
  • lib/webrick/utils.rb

Constants

RAND_CHARS

Characters used to generate random strings

Public Class Methods

create_listeners(address, port, logger=nil) click to toggle source

Creates TCP server sockets bound to address:port and returns them.

It will create IPV4 and IPV6 sockets on all interfaces.

# File lib/webrick/utils.rb, line 71
def create_listeners(address, port, logger=nil)
  unless port
    raise ArgumentError, "must specify port"
  end
  res = Socket::getaddrinfo(address, port,
                            Socket::AF_UNSPEC,   # address family
                            Socket::SOCK_STREAM, # socket type
                            0,                   # protocol
                            Socket::AI_PASSIVE)  # flag
  last_error = nil
  sockets = []
  res.each{|ai|
    begin
      logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger
      sock = TCPServer.new(ai[3], port)
      port = sock.addr[1] if port == 0
      Utils::set_close_on_exec(sock)
      sockets << sock
    rescue => ex
      logger.warn("TCPServer Error: #{ex}") if logger
      last_error  = ex
    end
  }
  raise last_error if sockets.empty?
  return sockets
end
create_self_signed_cert(bits, cn, comment) click to toggle source

Creates a self-signed certificate with the given number of bits, the issuer cn and a comment to be stored in the certificate.

# File lib/webrick/ssl.rb, line 91
def create_self_signed_cert(bits, cn, comment)
  rsa = OpenSSL::PKey::RSA.new(bits){|p, n|
    case p
    when 0; $stderr.putc "."  # BN_generate_prime
    when 1; $stderr.putc "+"  # BN_generate_prime
    when 2; $stderr.putc "*"  # searching good prime,
                              # n = #of try,
                              # but also data from BN_generate_prime
    when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
                              # but also data from BN_generate_prime
    else;   $stderr.putc "*"  # BN_generate_prime
    end
  }
  cert = OpenSSL::X509::Certificate.new
  cert.version = 2
  cert.serial = 1
  name = OpenSSL::X509::Name.new(cn)
  cert.subject = name
  cert.issuer = name
  cert.not_before = Time.now
  cert.not_after = Time.now + (365*24*60*60)
  cert.public_key = rsa.public_key

  ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
  ef.issuer_certificate = cert
  cert.extensions = [
    ef.create_extension("basicConstraints","CA:FALSE"),
    ef.create_extension("keyUsage", "keyEncipherment"),
    ef.create_extension("subjectKeyIdentifier", "hash"),
    ef.create_extension("extendedKeyUsage", "serverAuth"),
    ef.create_extension("nsComment", comment),
  ]
  aki = ef.create_extension("authorityKeyIdentifier",
                            "keyid:always,issuer:always")
  cert.add_extension(aki)
  cert.sign(rsa, OpenSSL::Digest::SHA1.new)

  return [ cert, rsa ]
end
getservername() click to toggle source

The server hostname

# File lib/webrick/utils.rb, line 57
def getservername
  host = Socket::gethostname
  begin
    Socket::gethostbyname(host)[0]
  rescue
    host
  end
end
random_string(len) click to toggle source

Generates a random string of length len

# File lib/webrick/utils.rb, line 107
def random_string(len)
  rand_max = RAND_CHARS.bytesize
  ret = ""
  len.times{ ret << RAND_CHARS[rand(rand_max)] }
  ret
end
set_close_on_exec(io) click to toggle source

Sets the close on exec flag for io

# File lib/webrick/utils.rb, line 34
def set_close_on_exec(io)
  if defined?(Fcntl::FD_CLOEXEC)
    io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
  end
end
set_non_blocking(io) click to toggle source

Sets IO operations on io to be non-blocking

# File lib/webrick/utils.rb, line 23
def set_non_blocking(io)
  flag = File::NONBLOCK
  if defined?(Fcntl::F_GETFL)
    flag |= io.fcntl(Fcntl::F_GETFL)
  end
  io.fcntl(Fcntl::F_SETFL, flag)
end
su(user) click to toggle source

Changes the process's uid and gid to the ones of user

# File lib/webrick/utils.rb, line 43
def su(user)
  if defined?(Etc)
    pw = Etc.getpwnam(user)
    Process::initgroups(user, pw.gid)
    Process::Sys::setgid(pw.gid)
    Process::Sys::setuid(pw.uid)
  else
    warn("WEBrick::Utils::su doesn't work on this platform")
  end
end
timeout(seconds, exception=Timeout::Error) { || ... } click to toggle source

Executes the passed block and raises exception if execution takes more than seconds.

If seconds is zero or nil, simply executes the block

# File lib/webrick/utils.rb, line 234
def timeout(seconds, exception=Timeout::Error)
  return yield if seconds.nil? or seconds.zero?
  # raise ThreadError, "timeout within critical session" if Thread.critical
  id = TimeoutHandler.register(seconds, exception)
  begin
    yield(seconds)
  ensure
    TimeoutHandler.cancel(id)
  end
end


class WEBrick::Utils::TimeoutHandler - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WEBrick::Utils::TimeoutHandler

Class used to manage timeout handlers across multiple threads.

Timeout handlers should be managed by using the class methods which are synchronized.

id = TimeoutHandler.register(10, Timeout::Error)
begin
  sleep 20
  puts 'foo'
ensure
  TimeoutHandler.cancel(id)
end

will raise Timeout::Error

id = TimeoutHandler.register(10, Timeout::Error)
begin
  sleep 5
  puts 'foo'
ensure
  TimeoutHandler.cancel(id)
end

will print 'foo'

In Files

  • lib/webrick/utils.rb

Parent

Object

Included Modules

  • Singleton

Public Class Methods

cancel(id) click to toggle source

Cancels the timeout handler id

# File lib/webrick/utils.rb, line 167
def TimeoutHandler.cancel(id)
  TimeoutMutex.synchronize{
    instance.cancel(Thread.current, id)
  }
end
new() click to toggle source

Creates a new TimeoutHandler. You should use ::register and ::cancel instead of creating the timeout handler directly.

# File lib/webrick/utils.rb, line 176
def initialize
  @timeout_info = Hash.new
  Thread.start{
    while true
      now = Time.now
      @timeout_info.keys.each{|thread|
        ary = @timeout_info[thread]
        next unless ary
        ary.dup.each{|info|
          time, exception = *info
          interrupt(thread, info.object_id, exception) if time < now
        }
      }
      sleep 0.5
    end
  }
end
register(seconds, exception) click to toggle source

Registers a new timeout handler

time

Timeout in seconds

exception

Exception to raise when timeout elapsed

# File lib/webrick/utils.rb, line 159
def TimeoutHandler.register(seconds, exception)
  TimeoutMutex.synchronize{
    instance.register(Thread.current, Time.now + seconds, exception)
  }
end

Public Instance Methods

cancel(thread, id) click to toggle source

Cancels the timeout handler id

# File lib/webrick/utils.rb, line 217
def cancel(thread, id)
  if ary = @timeout_info[thread]
    ary.delete_if{|info| info.object_id == id }
    if ary.empty?
      @timeout_info.delete(thread)
    end
    return true
  end
  return false
end
interrupt(thread, id, exception) click to toggle source

Interrupts the timeout handler id and raises exception

# File lib/webrick/utils.rb, line 196
def interrupt(thread, id, exception)
  TimeoutMutex.synchronize{
    if cancel(thread, id) && thread.alive?
      thread.raise(exception, "execution timeout")
    end
  }
end
register(thread, time, exception) click to toggle source

Registers a new timeout handler

time

Timeout in seconds

exception

Exception to raise when timeout elapsed

# File lib/webrick/utils.rb, line 209
def register(thread, time, exception)
  @timeout_info[thread] ||= Array.new
  @timeout_info[thread] << [time, exception]
  return @timeout_info[thread].last.object_id
end


class WIN32OLE - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WIN32OLE

<code>WIN32OLE</code> objects represent OLE Automation object in Ruby.

By using WIN32OLE, you can access OLE server like VBScript.

Here is sample script.

  require 'win32ole'

  excel = WIN32OLE.new('Excel.Application')
  excel.visible = true
  workbook = excel.Workbooks.Add();
  worksheet = workbook.Worksheets(1);
  worksheet.Range("A1:D1").value = ["North","South","East","West"];
  worksheet.Range("A2:B2").value = [5.2, 10];
  worksheet.Range("C2").value = 8;
  worksheet.Range("D2").value = 20;

  range = worksheet.Range("A1:D2");
  range.select
  chart = workbook.Charts.Add;

  workbook.saved = true;

  excel.ActiveWorkbook.Close(0);
  excel.Quit();

Unfortunately, Win32OLE doesn't support the argument passed by reference directly. Instead, Win32OLE provides WIN32OLE::ARGV. If you want to get the result value of argument passed by reference, you can use WIN32OLE::ARGV.

oleobj.method(arg1, arg2, refargv3)
puts WIN32OLE::ARGV[2]   # the value of refargv3 after called oleobj.method

In Files

  • ext/win32ole/win32ole.c

Parent

Object

Constants

ARGV
CP_ACP
CP_MACCP
CP_OEMCP
CP_SYMBOL
CP_THREAD_ACP
CP_UTF7
CP_UTF8
LOCALE_SYSTEM_DEFAULT
LOCALE_USER_DEFAULT
VERSION

Public Class Methods

codepage click to toggle source

Returns current codepage.

WIN32OLE.codepage # => WIN32OLE::CP_ACP

static VALUE
fole_s_get_code_page(VALUE self)
{
    return INT2FIX(cWIN32OLE_cp);
}
codepage = CP click to toggle source

Sets current codepage. The ::codepage is initialized according to Encoding.default_internal. If Encoding.default_internal is nil then ::codepage is initialized according to Encoding.default_external.

WIN32OLE.codepage = WIN32OLE::CP_UTF8
WIN32OLE.codepage = 65001
static VALUE
fole_s_set_code_page(VALUE self, VALUE vcp)
{
    UINT cp = FIX2INT(vcp);
    set_ole_codepage(cp);
    /*
     * Should this method return old codepage?
     */
    return Qnil;
}
connect( ole ) -→ aWIN32OLE click to toggle source

Returns running OLE Automation object or WIN32OLE object from moniker. 1st argument should be OLE program id or class id or moniker.

WIN32OLE.connect('Excel.Application') # => WIN32OLE object which represents running Excel.

static VALUE
fole_s_connect(int argc, VALUE *argv, VALUE self)
{
    VALUE svr_name;
    VALUE others;
    HRESULT hr;
    CLSID   clsid;
    OLECHAR *pBuf;
    IDispatch *pDispatch;
    void *p;
    IUnknown *pUnknown;

    rb_secure(4);
    /* initialize to use OLE */
    ole_initialize();

    rb_scan_args(argc, argv, "1*", &svr_name, &others);
    SafeStringValue(svr_name);
    if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
        rb_raise(rb_eSecurityError, "Insecure Object Connection - %s",
                 StringValuePtr(svr_name));
    }

    /* get CLSID from OLE server name */
    pBuf = ole_vstr2wc(svr_name);
    hr = CLSIDFromProgID(pBuf, &clsid);
    if(FAILED(hr)) {
        hr = CLSIDFromString(pBuf, &clsid);
    }
    SysFreeString(pBuf);
    if(FAILED(hr)) {
        return ole_bind_obj(svr_name, argc, argv, self);
    }

    hr = GetActiveObject(&clsid, 0, &pUnknown);
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "OLE server `%s' not running", StringValuePtr(svr_name));
    }
    hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, &p);
    pDispatch = p;
    if(FAILED(hr)) {
        OLE_RELEASE(pUnknown);
        ole_raise(hr, eWIN32OLERuntimeError,
                  "failed to create WIN32OLE server `%s'",
                  StringValuePtr(svr_name));
    }

    OLE_RELEASE(pUnknown);

    return create_win32ole_object(self, pDispatch, argc, argv);
}
const_load( ole, mod = WIN32OLE) click to toggle source

Defines the constants of OLE Automation server as mod's constants. The first argument is WIN32OLE object or type library name. If 2nd argument is omitted, the default is WIN32OLE. The first letter of Ruby's constant variable name is upper case, so constant variable name of WIN32OLE object is capitalized. For example, the 'xlTop' constant of Excel is changed to 'XlTop' in WIN32OLE. If the first letter of constant variabl is not [A-Z], then the constant is defined as CONSTANTS hash element.

module EXCEL_CONST
end
excel = WIN32OLE.new('Excel.Application')
WIN32OLE.const_load(excel, EXCEL_CONST)
puts EXCEL_CONST::XlTop # => -4160
puts EXCEL_CONST::CONSTANTS['_xlDialogChartSourceData'] # => 541

WIN32OLE.const_load(excel)
puts WIN32OLE::XlTop # => -4160

module MSO
end
WIN32OLE.const_load('Microsoft Office 9.0 Object Library', MSO)
puts MSO::MsoLineSingle # => 1

static VALUE
fole_s_const_load(int argc, VALUE *argv, VALUE self)
{
    VALUE ole;
    VALUE klass;
    struct oledata *pole;
    ITypeInfo *pTypeInfo;
    ITypeLib *pTypeLib;
    unsigned int index;
    HRESULT hr;
    OLECHAR *pBuf;
    VALUE file;
    LCID    lcid = cWIN32OLE_lcid;

    rb_secure(4);
    rb_scan_args(argc, argv, "11", &ole, &klass);
    if (TYPE(klass) != T_CLASS &&
        TYPE(klass) != T_MODULE &&
        TYPE(klass) != T_NIL) {
        rb_raise(rb_eTypeError, "2nd parameter must be Class or Module");
    }
    if (rb_obj_is_kind_of(ole, cWIN32OLE)) {
        OLEData_Get_Struct(ole, pole);
        hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
                                                  0, lcid, &pTypeInfo);
        if(FAILED(hr)) {
            ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
        }
        hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
        if(FAILED(hr)) {
            OLE_RELEASE(pTypeInfo);
            ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
        }
        OLE_RELEASE(pTypeInfo);
        if(TYPE(klass) != T_NIL) {
            ole_const_load(pTypeLib, klass, self);
        }
        else {
            ole_const_load(pTypeLib, cWIN32OLE, self);
        }
        OLE_RELEASE(pTypeLib);
    }
    else if(TYPE(ole) == T_STRING) {
        file = typelib_file(ole);
        if (file == Qnil) {
            file = ole;
        }
        pBuf = ole_vstr2wc(file);
        hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib);
        SysFreeString(pBuf);
        if (FAILED(hr))
          ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
        if(TYPE(klass) != T_NIL) {
            ole_const_load(pTypeLib, klass, self);
        }
        else {
            ole_const_load(pTypeLib, cWIN32OLE, self);
        }
        OLE_RELEASE(pTypeLib);
    }
    else {
        rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE instance");
    }
    return Qnil;
}
create_guid click to toggle source

Creates GUID.

WIN32OLE.create_guid # => {1CB530F1-F6B1-404D-BCE6-1959BF91F4A8}

static VALUE
fole_s_create_guid(VALUE self)
{
    GUID guid;
    HRESULT hr;
    OLECHAR bstr[80];
    int len = 0;
    hr = CoCreateGuid(&guid);
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "failed to create GUID");
    }
    len = StringFromGUID2(&guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
    if (len == 0) {
        rb_raise(rb_eRuntimeError, "failed to create GUID(buffer over)");
    }
    return ole_wc2vstr(bstr, FALSE);
}
locale → locale id. click to toggle source

Returns current locale id (lcid). The default locale is LOCALE_SYSTEM_DEFAULT.

lcid = WIN32OLE.locale
static VALUE
fole_s_get_locale(VALUE self)
{
    return INT2FIX(cWIN32OLE_lcid);
}
locale = lcid click to toggle source

Sets current locale id (lcid).

WIN32OLE.locale = 1033 # set locale English(U.S)
obj = WIN32OLE_VARIANT.new("$100,000", WIN32OLE::VARIANT::VT_CY)
static VALUE
fole_s_set_locale(VALUE self, VALUE vlcid)
{
    LCID lcid = FIX2INT(vlcid);
    if (lcid_installed(lcid)) {
        cWIN32OLE_lcid = lcid;
    } else {
        switch (lcid) {
        case LOCALE_SYSTEM_DEFAULT:
        case LOCALE_USER_DEFAULT:
            cWIN32OLE_lcid = lcid;
            break;
        default:
            rb_raise(eWIN32OLERuntimeError, "not installed locale: %u", (unsigned int)lcid);
        }
    }
    return Qnil;
}
new(server, [host]) → WIN32OLE object click to toggle source

Returns a new WIN32OLE object(OLE Automation object). The first argument server specifies OLE Automation server. The first argument should be CLSID or PROGID. If second argument host specified, then returns OLE Automation object on host.

WIN32OLE.new('Excel.Application') # => Excel OLE Automation WIN32OLE object.
WIN32OLE.new('{00024500-0000-0000-C000-000000000046}') # => Excel OLE Automation WIN32OLE object.

static VALUE
fole_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE svr_name;
    VALUE host;
    VALUE others;
    HRESULT hr;
    CLSID   clsid;
    OLECHAR *pBuf;
    IDispatch *pDispatch;
    void *p;
    rb_secure(4);
    rb_call_super(0, 0);
    rb_scan_args(argc, argv, "11*", &svr_name, &host, &others);

    SafeStringValue(svr_name);
    if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
        rb_raise(rb_eSecurityError, "Insecure Object Creation - %s",
                 StringValuePtr(svr_name));
    }
    if (!NIL_P(host)) {
        SafeStringValue(host);
        if (rb_safe_level() > 0 && OBJ_TAINTED(host)) {
            rb_raise(rb_eSecurityError, "Insecure Object Creation - %s",
                     StringValuePtr(svr_name));
        }
        return ole_create_dcom(self, svr_name, host, others);
    }

    /* get CLSID from OLE server name */
    pBuf  = ole_vstr2wc(svr_name);
    hr = CLSIDFromProgID(pBuf, &clsid);
    if(FAILED(hr)) {
        hr = CLSIDFromString(pBuf, &clsid);
    }
    SysFreeString(pBuf);
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "unknown OLE server: `%s'",
                  StringValuePtr(svr_name));
    }

    /* get IDispatch interface */
    hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
                          &IID_IDispatch, &p);
    pDispatch = p;
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "failed to create WIN32OLE object from `%s'",
                  StringValuePtr(svr_name));
    }

    ole_set_member(self, pDispatch);
    return self;
}
ole_free(aWIN32OLE) -→ number click to toggle source

Invokes Release method of Dispatch interface of WIN32OLE object. You should not use this method because this method exists only for debugging WIN32OLE. The return value is reference counter of OLE object.

static VALUE
fole_s_free(VALUE self, VALUE obj)
{
    ULONG n = 0;
    struct oledata * pole;
    OLEData_Get_Struct(obj, pole);
    if(pole->pDispatch) {
        if (reference_count(pole) > 0) {
            n = OLE_RELEASE(pole->pDispatch);
        }
    }
    return INT2NUM(n);
}
ole_initialize() click to toggle source

:nodoc

static VALUE
fole_s_ole_initialize(VALUE self)
{
    ole_initialize();
    return Qnil;
}
ole_reference_count(aWIN32OLE) -→ number click to toggle source

Returns reference counter of Dispatch interface of WIN32OLE object. You should not use this method because this method exists only for debugging WIN32OLE.

static VALUE
fole_s_reference_count(VALUE self, VALUE obj)
{
    struct oledata * pole;
    OLEData_Get_Struct(obj, pole);
    return INT2NUM(reference_count(pole));
}
ole_show_help(obj [,helpcontext]) click to toggle source

Displays helpfile. The 1st argument specifies WIN32OLE_TYPE object or WIN32OLE_METHOD object or helpfile.

excel = WIN32OLE.new('Excel.Application')
typeobj = excel.ole_type
WIN32OLE.ole_show_help(typeobj)
static VALUE
fole_s_show_help(int argc, VALUE *argv, VALUE self)
{
    VALUE target;
    VALUE helpcontext;
    VALUE helpfile;
    VALUE name;
    HWND  hwnd;
    rb_scan_args(argc, argv, "11", &target, &helpcontext);
    if (rb_obj_is_kind_of(target, cWIN32OLE_TYPE) ||
        rb_obj_is_kind_of(target, cWIN32OLE_METHOD)) {
        helpfile = rb_funcall(target, rb_intern("helpfile"), 0);
        if(strlen(StringValuePtr(helpfile)) == 0) {
            name = rb_ivar_get(target, rb_intern("name"));
            rb_raise(rb_eRuntimeError, "no helpfile of `%s'",
                     StringValuePtr(name));
        }
        helpcontext = rb_funcall(target, rb_intern("helpcontext"), 0);
    } else {
        helpfile = target;
    }
    if (TYPE(helpfile) != T_STRING) {
        rb_raise(rb_eTypeError, "1st parameter must be (String|WIN32OLE_TYPE|WIN32OLE_METHOD)");
    }
    hwnd = ole_show_help(helpfile, helpcontext);
    if(hwnd == 0) {
        rb_raise(rb_eRuntimeError, "failed to open help file `%s'",
                 StringValuePtr(helpfile));
    }
    return Qnil;
}
ole_uninitialize() click to toggle source

:nodoc

static VALUE
fole_s_ole_uninitialize(VALUE self)
{
    ole_uninitialize();
    return Qnil;
}

Public Instance Methods

WIN32OLE[a1,a2,...] click to toggle source

Returns the value of Collection specified by a1, a2,.…

dict = WIN32OLE.new('Scripting.Dictionary')
dict.add('ruby', 'Ruby')
puts dict['ruby'] # => 'Ruby' (same as `puts dict.item('ruby')')

Remark: You can not use this method to get the property.

excel = WIN32OLE.new('Excel.Application')
# puts excel['Visible']  This is error !!!
puts excel.Visible # You should to use this style to get the property.
static VALUE
fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self)
{
    return ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE);
}
WIN32OLE[a1, a2, ...]=val click to toggle source

Sets the value to WIN32OLE object specified by a1, a2, …

dict = WIN32OLE.new('Scripting.Dictionary')
dict.add('ruby', 'RUBY')
dict['ruby'] = 'Ruby'
puts dict['ruby'] # => 'Ruby'

Remark: You can not use this method to set the property value.

excel = WIN32OLE.new('Excel.Application')
# excel['Visible'] = true # This is error !!!
excel.Visible = true # You should to use this style to set the property.
static VALUE
fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self)
{
    return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, TRUE);
}
WIN32OLE#_getproperty(dispid, args, types) click to toggle source

Runs the early binding method to get property. The 1st argument specifies dispatch ID, the 2nd argument specifies the array of arguments, the 3rd argument specifies the array of the type of arguments.

excel = WIN32OLE.new('Excel.Application')
puts excel._getproperty(558, [], []) # same effect as puts excel.visible
static VALUE
fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
{
    return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYGET);
}
WIN32OLE#_invoke(dispid, args, types) click to toggle source

Runs the early binding method. The 1st argument specifies dispatch ID, the 2nd argument specifies the array of arguments, the 3rd argument specifies the array of the type of arguments.

excel = WIN32OLE.new('Excel.Application')
excel._invoke(302, [], []) #  same effect as excel.Quit
static VALUE
fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types)
{
    return ole_invoke2(self, dispid, args, types, DISPATCH_METHOD);
}
WIN32OLE#_setproperty(dispid, args, types) click to toggle source

Runs the early binding method to set property. The 1st argument specifies dispatch ID, the 2nd argument specifies the array of arguments, the 3rd argument specifies the array of the type of arguments.

excel = WIN32OLE.new('Excel.Application')
excel._setproperty(558, [true], [WIN32OLE::VARIANT::VT_BOOL]) # same effect as excel.visible = true
static VALUE
fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
{
    return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYPUT);
}
WIN32OLE#each {|i|...} click to toggle source

Iterates over each item of OLE collection which has IEnumVARIANT interface.

excel = WIN32OLE.new('Excel.Application')
book = excel.workbooks.add
sheets = book.worksheets(1)
cells = sheets.cells("A1:A5")
cells.each do |cell|
  cell.value = 10
end

static VALUE
fole_each(VALUE self)
{
    LCID    lcid = cWIN32OLE_lcid;

    struct oledata *pole;

    unsigned int argErr;
    EXCEPINFO excepinfo;
    DISPPARAMS dispParams;
    VARIANT result;
    HRESULT hr;
    IEnumVARIANT *pEnum = NULL;
    void *p;

    RETURN_ENUMERATOR(self, 0, 0);

    VariantInit(&result);
    dispParams.rgvarg = NULL;
    dispParams.rgdispidNamedArgs = NULL;
    dispParams.cNamedArgs = 0;
    dispParams.cArgs = 0;
    memset(&excepinfo, 0, sizeof(excepinfo));

    OLEData_Get_Struct(self, pole);
    hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DISPID_NEWENUM,
                                         &IID_NULL, lcid,
                                         DISPATCH_METHOD | DISPATCH_PROPERTYGET,
                                         &dispParams, &result,
                                         &excepinfo, &argErr);

    if (FAILED(hr)) {
        VariantClear(&result);
        ole_raise(hr, eWIN32OLERuntimeError, "failed to get IEnum Interface");
    }

    if (V_VT(&result) == VT_UNKNOWN) {
        hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result),
                                                        &IID_IEnumVARIANT,
                                                        &p);
        pEnum = p;
    } else if (V_VT(&result) == VT_DISPATCH) {
        hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result),
                                                         &IID_IEnumVARIANT,
                                                         &p);
        pEnum = p;
    }
    if (FAILED(hr) || !pEnum) {
        VariantClear(&result);
        ole_raise(hr, rb_eRuntimeError, "failed to get IEnum Interface");
    }

    VariantClear(&result);
    rb_ensure(ole_each_sub, (VALUE)pEnum, ole_ienum_free, (VALUE)pEnum);
    return Qnil;
}
WIN32OLE#invoke(method, [arg1,...]) → return value of method. click to toggle source

Runs OLE method. The first argument specifies the method name of OLE Automation object. The others specify argument of the method. If you can not execute method directly, then use this method instead.

excel = WIN32OLE.new('Excel.Application')
excel.invoke('Quit')  # => same as excel.Quit

static VALUE
fole_invoke(int argc, VALUE *argv, VALUE self)
{
    return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
}
WIN32OLE#method_missing(id [,arg1, arg2, ...]) click to toggle source

Calls #invoke method.

static VALUE
fole_missing(int argc, VALUE *argv, VALUE self)
{
    ID id;
    const char* mname;
    int n;
    id = rb_to_id(argv[0]);
    mname = rb_id2name(id);
    if(!mname) {
        rb_raise(rb_eRuntimeError, "fail: unknown method or property");
    }
    n = strlen(mname);
    if(mname[n-1] == '=') {
        argv[0] = rb_enc_str_new(mname, n-1, cWIN32OLE_enc);

        return ole_propertyput(self, argv[0], argv[1]);
    }
    else {
        argv[0] = rb_enc_str_new(mname, n, cWIN32OLE_enc);
        return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
    }
}
WIN32OLE#ole_activex_initialize() → Qnil click to toggle source

Initialize WIN32OLE object(ActiveX Control) by calling IPersistMemory::InitNew.

Before calling OLE method, some kind of the ActiveX controls created with MFC should be initialized by calling IPersistXXX::InitNew.

If and only if you received the exception “HRESULT error code: 0x8000ffff catastrophic failure”, try this method before invoking any ole_method.

obj = WIN32OLE.new("ProgID_or_GUID_of_ActiveX_Control")
obj.ole_activex_initialize
obj.method(...)
static VALUE
fole_activex_initialize(VALUE self)
{
    struct oledata *pole;
    IPersistMemory *pPersistMemory;
    void *p;

    HRESULT hr = S_OK;

    OLEData_Get_Struct(self, pole);

    hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &IID_IPersistMemory, &p);
    pPersistMemory = p;
    if (SUCCEEDED(hr)) {
        hr = pPersistMemory->lpVtbl->InitNew(pPersistMemory);
        OLE_RELEASE(pPersistMemory);
        if (SUCCEEDED(hr)) {
            return Qnil;
        }
    }

    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "fail to initialize ActiveX control");
    }

    return Qnil;
}
WIN32OLE#ole_free click to toggle source

invokes Release method of Dispatch interface of WIN32OLE object. Usually, you do not need to call this method because Release method called automatically when WIN32OLE object garbaged.

static VALUE
fole_free(VALUE self)
{
    struct oledata *pole;
    rb_secure(4);
    OLEData_Get_Struct(self, pole);
    OLE_FREE(pole->pDispatch);
    pole->pDispatch = NULL;
    return Qnil;
}
WIN32OLE#ole_func_methods click to toggle source

Returns the array of WIN32OLE_METHOD object . The element of the array is property (settable) of WIN32OLE object.

excel = WIN32OLE.new('Excel.Application')
properties = excel.ole_func_methods
static VALUE
fole_func_methods(VALUE self)
{
    return ole_methods( self, INVOKE_FUNC);
}
WIN32OLE#ole_get_methods click to toggle source

Returns the array of WIN32OLE_METHOD object . The element of the array is property (gettable) of WIN32OLE object.

excel = WIN32OLE.new('Excel.Application')
properties = excel.ole_get_methods
static VALUE
fole_get_methods(VALUE self)
{
    return ole_methods( self, INVOKE_PROPERTYGET);
}
WIN32OLE#ole_method_help(method) click to toggle source

Returns WIN32OLE_METHOD object corresponding with method specified by 1st argument.

excel = WIN32OLE.new('Excel.Application')
method = excel.ole_method_help('Quit')
static VALUE
fole_method_help(VALUE self, VALUE cmdname)
{
    ITypeInfo *pTypeInfo;
    HRESULT hr;
    struct oledata *pole;
    VALUE method, obj;

    SafeStringValue(cmdname);
    OLEData_Get_Struct(self, pole);
    hr = typeinfo_from_ole(pole, &pTypeInfo);
    if(FAILED(hr))
        ole_raise(hr, rb_eRuntimeError, "failed to get ITypeInfo");
    method = folemethod_s_allocate(cWIN32OLE_METHOD);
    obj = olemethod_from_typeinfo(method, pTypeInfo, cmdname);
    OLE_RELEASE(pTypeInfo);
    if (obj == Qnil)
        rb_raise(eWIN32OLERuntimeError, "not found %s",
                 StringValuePtr(cmdname));
    return obj;
}
Also aliased as: ole_method_help
ole_method_help(p1) click to toggle source
Alias for: ole_method
WIN32OLE#ole_methods click to toggle source

Returns the array of WIN32OLE_METHOD object. The element is OLE method of WIN32OLE object.

excel = WIN32OLE.new('Excel.Application')
methods = excel.ole_methods
static VALUE
fole_methods(VALUE self)
{
    return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
}
ole_obj_help() click to toggle source
Alias for: ole_type
WIN32OLE#ole_put_methods click to toggle source

Returns the array of WIN32OLE_METHOD object . The element of the array is property (settable) of WIN32OLE object.

excel = WIN32OLE.new('Excel.Application')
properties = excel.ole_put_methods
static VALUE
fole_put_methods(VALUE self)
{
    return ole_methods( self, INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF);
}
WIN32OLE#ole_query_interface(iid) → WIN32OLE object click to toggle source

Returns WIN32OLE object for a specific dispatch or dual interface specified by iid.

ie = WIN32OLE.new('InternetExplorer.Application')
ie_web_app = ie.ole_query_interface('{0002DF05-0000-0000-C000-000000000046}') # => WIN32OLE object for dispinterface IWebBrowserApp

static VALUE
fole_query_interface(VALUE self, VALUE str_iid)
{
    HRESULT hr;
    OLECHAR *pBuf;
    IID iid;
    struct oledata *pole;
    IDispatch *pDispatch;
    void *p;

    pBuf  = ole_vstr2wc(str_iid);
    hr = CLSIDFromString(pBuf, &iid);
    SysFreeString(pBuf);
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "invalid iid: `%s'",
                  StringValuePtr(str_iid));
    }

    OLEData_Get_Struct(self, pole);
    if(!pole->pDispatch) {
        rb_raise(rb_eRuntimeError, "failed to get dispatch interface");
    }

    hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &iid,
                                                 &p);
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "failed to get interface `%s'",
                  StringValuePtr(str_iid));
    }

    pDispatch = p;
    return create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
}
WIN32OLE#ole_respond_to?(method) → true or false click to toggle source

Returns true when OLE object has OLE method, otherwise returns false.

ie = WIN32OLE.new('InternetExplorer.Application')
ie.ole_respond_to?("gohome") => true

static VALUE
fole_respond_to(VALUE self, VALUE method)
{
    struct oledata *pole;
    BSTR wcmdname;
    DISPID DispID;
    HRESULT hr;
    rb_secure(4);
    if(TYPE(method) != T_STRING && TYPE(method) != T_SYMBOL) {
        rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
    }
    if (TYPE(method) == T_SYMBOL) {
        method = rb_sym_to_s(method);
    }
    OLEData_Get_Struct(self, pole);
    wcmdname = ole_vstr2wc(method);
    hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
            &wcmdname, 1, cWIN32OLE_lcid, &DispID);
    SysFreeString(wcmdname);
    return SUCCEEDED(hr) ? Qtrue : Qfalse;
}
WIN32OLE#ole_type click to toggle source

Returns WIN32OLE_TYPE object.

excel = WIN32OLE.new('Excel.Application')
tobj = excel.ole_type
static VALUE
fole_type(VALUE self)
{
    ITypeInfo *pTypeInfo;
    HRESULT hr;
    struct oledata *pole;
    LCID  lcid = cWIN32OLE_lcid;
    VALUE type = Qnil;

    OLEData_Get_Struct(self, pole);

    hr = pole->pDispatch->lpVtbl->GetTypeInfo( pole->pDispatch, 0, lcid, &pTypeInfo );
    if(FAILED(hr)) {
        ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
    }
    type = ole_type_from_itypeinfo(pTypeInfo);
    OLE_RELEASE(pTypeInfo);
    if (type == Qnil) {
        rb_raise(rb_eRuntimeError, "failed to create WIN32OLE_TYPE obj from ITypeInfo");
    }
    return type;
}
Also aliased as: ole_obj_help
WIN32OLE#ole_typelib → The WIN32OLE_TYPELIB object click to toggle source

Returns the WIN32OLE_TYPELIB object. The object represents the type library which contains the WIN32OLE object.

excel = WIN32OLE.new('Excel.Application')
tlib = excel.ole_typelib
puts tlib.name  # -> 'Microsoft Excel 9.0 Object Library'
static VALUE
fole_typelib(VALUE self)
{
    struct oledata *pole;
    HRESULT hr;
    ITypeInfo *pTypeInfo;
    LCID  lcid = cWIN32OLE_lcid;
    VALUE vtlib = Qnil;

    OLEData_Get_Struct(self, pole);
    hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
                                              0, lcid, &pTypeInfo);
    if(FAILED(hr)) {
        ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
    }
    vtlib = ole_typelib_from_itypeinfo(pTypeInfo);
    OLE_RELEASE(pTypeInfo);
    if (vtlib == Qnil) {
        rb_raise(rb_eRuntimeError, "failed to get type library info.");
    }
    return vtlib;
}
setproperty('property', [arg1, arg2,...] val) click to toggle source

Sets property of OLE object. When you want to set property with argument, you can use this method.

excel = WIN32OLE.new('Excel.Application')
excel.Visible = true
book = excel.workbooks.add
sheet = book.worksheets(1)
sheet.setproperty('Cells', 1, 2, 10) # => The B1 cell value is 10.

static VALUE
fole_setproperty(int argc, VALUE *argv, VALUE self)
{
    return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE);
}


module WIN32OLE::VARIANT - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module WIN32OLE::VARIANT

In Files

  • ext/win32ole/win32ole.c

Constants

VT_ARRAY
VT_BOOL
VT_BSTR
VT_BYREF
VT_CY
VT_DATE
VT_DISPATCH
VT_EMPTY
VT_ERROR
VT_I1
VT_I2
VT_I4
VT_I8
VT_INT
VT_NULL
VT_PTR
VT_R4
VT_R8
VT_UI1
VT_UI2
VT_UI4
VT_UI8
VT_UINT
VT_UNKNOWN
VT_USERDEFINED
VT_VARIANT


class WIN32OLERuntimeError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WIN32OLERuntimeError

In Files

  • ext/win32ole/win32ole.c

Parent

RuntimeError


class WIN32OLE_EVENT - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WIN32OLE_EVENT

WIN32OLE_EVENT objects controls OLE event.

In Files

  • ext/win32ole/win32ole.c

Parent

Object

Public Class Methods

message_loop click to toggle source

Translates and dispatches Windows message.

static VALUE
fev_s_msg_loop(VALUE klass)
{
    ole_msg_loop();
    return Qnil;
}
new(ole, event) #→ WIN32OLE_EVENT object. click to toggle source

Returns OLE event object. The first argument specifies WIN32OLE object. The second argument specifies OLE event name.

ie = WIN32OLE.new('InternetExplorer.Application')
ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents')
static VALUE
fev_initialize(int argc, VALUE *argv, VALUE self)
{
    ev_advise(argc, argv, self);
    evs_push(self);
    rb_ivar_set(self, id_events, rb_ary_new());
    fev_set_handler(self, Qnil);
    return self;
}

Public Instance Methods

WIN32OLE_EVENT#handler click to toggle source

returns handler object.

static VALUE
fev_get_handler(VALUE self)
{
    return rb_ivar_get(self, rb_intern("handler"));
}
WIN32OLE_EVENT#handler= click to toggle source

sets event handler object. If handler object has onXXX method according to XXX event, then onXXX method is called when XXX event occurs.

If handler object has method_missing and there is no method according to the event, then method_missing called and 1-st argument is event name.

If handler object has onXXX method and there is block defined by #on_event('XXX'){}, then block is executed but handler object method is not called when XXX event occurs.

class Handler
  def onStatusTextChange(text)
    puts "StatusTextChanged"
  end
  def onPropertyChange(prop)
    puts "PropertyChanged"
  end
  def method_missing(ev, *arg)
    puts "other event #{ev}"
  end
end

handler = Handler.new
ie = WIN32OLE.new('InternetExplorer.Application')
ev = WIN32OLE_EVENT.new(ie)
ev.on_event("StatusTextChange") {|*args|
  puts "this block executed."
  puts "handler.onStatusTextChange method is not called."
}
ev.handler = handler

static VALUE
fev_set_handler(VALUE self, VALUE val)
{
    return rb_ivar_set(self, rb_intern("handler"), val);
}
WIN32OLE_EVENT#off_event([event]) click to toggle source

removes the callback of event.

ie = WIN32OLE.new('InternetExplorer.Application')
ev = WIN32OLE_EVENT.new(ie)
ev.on_event('BeforeNavigate2') {|*args|
  args.last[6] = true
}
  ...
ev.off_event('BeforeNavigate2')
  ...

static VALUE
fev_off_event(int argc, VALUE *argv, VALUE self)
{
    VALUE event = Qnil;
    VALUE events;

    rb_secure(4);
    rb_scan_args(argc, argv, "01", &event);
    if(!NIL_P(event)) {
        if(TYPE(event) != T_STRING && TYPE(event) != T_SYMBOL) {
            rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
        }
        if (TYPE(event) == T_SYMBOL) {
            event = rb_sym_to_s(event);
        }
    }
    events = rb_ivar_get(self, id_events);
    if (NIL_P(events)) {
        return Qnil;
    }
    ole_delete_event(events, event);
    return Qnil;
}
WIN32OLE_EVENT#on_event([event]){...} click to toggle source

Defines the callback event. If argument is omitted, this method defines the callback of all events. If you want to modify reference argument in callback, return hash in callback. If you want to return value to OLE server as result of callback use `return' or :return.

ie = WIN32OLE.new('InternetExplorer.Application')
ev = WIN32OLE_EVENT.new(ie)
ev.on_event("NavigateComplete") {|url| puts url}
ev.on_event() {|ev, *args| puts "#{ev} fired"}

ev.on_event("BeforeNavigate2") {|*args|
  ...
  # set true to BeforeNavigate reference argument `Cancel'.
  # Cancel is 7-th argument of BeforeNavigate,
  # so you can use 6 as key of hash instead of 'Cancel'.
  # The argument is counted from 0.
  # The hash key of 0 means first argument.)
  {:Cancel => true}  # or {'Cancel' => true} or {6 => true}
}

ev.on_event(...) {|*args|
  {:return => 1, :xxx => yyy}
}

static VALUE
fev_on_event(int argc, VALUE *argv, VALUE self)
{
    return ev_on_event(argc, argv, self, Qfalse);
}
WIN32OLE_EVENT#on_event_with_outargs([event]){...} click to toggle source

Defines the callback of event. If you want modify argument in callback, you could use this method instead of #on_event.

ie = WIN32OLE.new('InternetExplorer.Application')
ev = WIN32OLE_EVENT.new(ie)
ev.on_event_with_outargs('BeforeNavigate2') {|*args|
  args.last[6] = true
}

static VALUE
fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self)
{
    return ev_on_event(argc, argv, self, Qtrue);
}
WIN32OLE_EVENT#unadvise → nil click to toggle source

disconnects OLE server. If this method called, then the WIN32OLE_EVENT object does not receive the OLE server event any more. This method is trial implementation.

ie = WIN32OLE.new('InternetExplorer.Application')
ev = WIN32OLE_EVENT.new(ie)
ev.on_event() {...}
   ...
ev.unadvise
static VALUE
fev_unadvise(VALUE self)
{
    struct oleeventdata *poleev;
    Data_Get_Struct(self, struct oleeventdata, poleev);
    if (poleev->pConnectionPoint) {
        ole_msg_loop();
        evs_delete(poleev->event_id);
        poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie);
        OLE_RELEASE(poleev->pConnectionPoint);
        poleev->pConnectionPoint = NULL;
    }
    return Qnil;
}


class WIN32OLE_METHOD - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WIN32OLE_METHOD

WIN32OLE_METHOD objects represent OLE method information.

In Files

  • ext/win32ole/win32ole.c

Parent

Object

Public Class Methods

new(ole_type, method) → WIN32OLE_METHOD object click to toggle source

Returns a new WIN32OLE_METHOD object which represents the information about OLE method. The first argument ole_type specifies WIN32OLE_TYPE object. The second argument method specifies OLE method name defined OLE class which represents WIN32OLE_TYPE object.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
static VALUE
folemethod_initialize(VALUE self, VALUE oletype, VALUE method)
{
    struct oletypedata *ptype;
    VALUE obj = Qnil;
    if (rb_obj_is_kind_of(oletype, cWIN32OLE_TYPE)) {
        SafeStringValue(method);
        Data_Get_Struct(oletype, struct oletypedata, ptype);
        obj = olemethod_from_typeinfo(self, ptype->pTypeInfo, method);
        if (obj == Qnil) {
            rb_raise(eWIN32OLERuntimeError, "not found %s",
                     StringValuePtr(method));
        }
    }
    else {
        rb_raise(rb_eTypeError, "1st argument should be WIN32OLE_TYPE object");
    }
    return obj;
}

Public Instance Methods

WIN32OLE_METHOD#dispid click to toggle source

Returns dispatch ID.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
method = WIN32OLE_METHOD.new(tobj, 'Add')
puts method.dispid # => 181

static VALUE
folemethod_dispid(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_dispid(pmethod->pTypeInfo, pmethod->index);
}
WIN32OLE_METHOD#event? click to toggle source

Returns true if the method is event.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SheetActivate')
puts method.event? # => true

static VALUE
folemethod_event(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    if (!pmethod->pOwnerTypeInfo)
        return Qfalse;
    return ole_method_event(pmethod->pOwnerTypeInfo,
                            pmethod->index,
                            rb_ivar_get(self, rb_intern("name")));
}
WIN32OLE_METHOD#event_interface click to toggle source

Returns event interface name if the method is event.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SheetActivate')
puts method.event_interface # =>  WorkbookEvents

static VALUE
folemethod_event_interface(VALUE self)
{
    BSTR name;
    struct olemethoddata *pmethod;
    HRESULT hr;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    if(folemethod_event(self) == Qtrue) {
        hr = ole_docinfo_from_type(pmethod->pTypeInfo, &name, NULL, NULL, NULL);
        if(SUCCEEDED(hr))
            return WC2VSTR(name);
    }
    return Qnil;
}
WIN32OLE_METHOD#helpcontext click to toggle source

Returns help context.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
method = WIN32OLE_METHOD.new(tobj, 'Add')
puts method.helpcontext # => 65717

static VALUE
folemethod_helpcontext(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_helpcontext(pmethod->pTypeInfo, pmethod->index);
}
WIN32OLE_METHOD#helpfile click to toggle source

Returns help file. If help file is not found, then the method returns nil.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
method = WIN32OLE_METHOD.new(tobj, 'Add')
puts method.helpfile # => C:\...\VBAXL9.CHM

static VALUE
folemethod_helpfile(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);

    return ole_method_helpfile(pmethod->pTypeInfo, pmethod->index);
}
WIN32OLE_METHOD#helpstring click to toggle source

Returns help string of OLE method. If the help string is not found, then the method returns nil.

tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser')
method = WIN32OLE_METHOD.new(tobj, 'Navigate')
puts method.helpstring # => Navigates to a URL or file.

static VALUE
folemethod_helpstring(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_helpstring(pmethod->pTypeInfo, pmethod->index);
}
WIN32OLE_METHOD#inspect → String click to toggle source

Returns the method name with class name.

static VALUE
folemethod_inspect(VALUE self)
{
    return default_inspect(self, "WIN32OLE_METHOD");
}
WIN32OLE_MTHOD#invkind click to toggle source

Returns the method invoke kind.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
method = WIN32OLE_METHOD.new(tobj, 'Add')
puts method.invkind # => 1

static VALUE
folemethod_invkind(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_invkind(pmethod->pTypeInfo, pmethod->index);
}
WIN32OLE_METHOD#invoke_kind click to toggle source

Returns the method kind string. The string is “UNKNOWN” or “PROPERTY” or “PROPERTY” or “PROPERTYGET” or “PROPERTYPUT” or “PROPERTYPPUTREF” or “FUNC”.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
method = WIN32OLE_METHOD.new(tobj, 'Add')
puts method.invoke_kind # => "FUNC"

static VALUE
folemethod_invoke_kind(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_invoke_kind(pmethod->pTypeInfo, pmethod->index);
}
name() click to toggle source

call-seq

WIN32OLE_METHOD#name

Returns the name of the method.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
puts method.name # => SaveAs

static VALUE
folemethod_name(VALUE self)
{
    return rb_ivar_get(self, rb_intern("name"));
}
Also aliased as: to_s
WIN32OLE_METHOD#offset_vtbl click to toggle source

Returns the offset ov VTBL.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
method = WIN32OLE_METHOD.new(tobj, 'Add')
puts method.offset_vtbl # => 40

static VALUE
folemethod_offset_vtbl(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_offset_vtbl(pmethod->pTypeInfo, pmethod->index);
}
WIN32OLE_METHOD#params click to toggle source

returns array of WIN32OLE_PARAM object corresponding with method parameters.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
p method.params # => [Filename, FileFormat, Password, WriteResPassword,
                      ReadOnlyRecommended, CreateBackup, AccessMode,
                      ConflictResolution, AddToMru, TextCodepage,
                      TextVisualLayout]

static VALUE
folemethod_params(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_params(pmethod->pTypeInfo, pmethod->index);
}
WIN32OLE_METHOD#return_type click to toggle source

Returns string of return value type of method.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
method = WIN32OLE_METHOD.new(tobj, 'Add')
puts method.return_type # => Workbook

static VALUE
folemethod_return_type(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_return_type(pmethod->pTypeInfo, pmethod->index);
}
WIN32OLE_METHOD#return_type_detail click to toggle source

Returns detail information of return value type of method. The information is array.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
method = WIN32OLE_METHOD.new(tobj, 'Add')
p method.return_type_detail # => ["PTR", "USERDEFINED", "Workbook"]

static VALUE
folemethod_return_type_detail(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_return_type_detail(pmethod->pTypeInfo, pmethod->index);
}
WIN32OLE_METHOD#return_vtype click to toggle source

Returns number of return value type of method.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
method = WIN32OLE_METHOD.new(tobj, 'Add')
puts method.return_vtype # => 26

static VALUE
folemethod_return_vtype(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_return_vtype(pmethod->pTypeInfo, pmethod->index);
}
WIN32OLE_METHOD#size_opt_params click to toggle source

Returns the size of optional parameters.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
puts method.size_opt_params # => 4

static VALUE
folemethod_size_opt_params(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_size_opt_params(pmethod->pTypeInfo, pmethod->index);
}
WIN32OLE_METHOD#size_params click to toggle source

Returns the size of arguments of the method.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
puts method.size_params # => 11

static VALUE
folemethod_size_params(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_size_params(pmethod->pTypeInfo, pmethod->index);
}
to_s() click to toggle source
Alias for: name
WIN32OLE_METHOD#visible? click to toggle source

Returns true if the method is public.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
method = WIN32OLE_METHOD.new(tobj, 'Add')
puts method.visible? # => true

static VALUE
folemethod_visible(VALUE self)
{
    struct olemethoddata *pmethod;
    Data_Get_Struct(self, struct olemethoddata, pmethod);
    return ole_method_visible(pmethod->pTypeInfo, pmethod->index);
}


class WIN32OLE_PARAM - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WIN32OLE_PARAM

WIN32OLE_PARAM objects represent param information of the OLE method.

In Files

  • ext/win32ole/win32ole.c

Parent

Object

Public Class Methods

new(p1, p2) click to toggle source
static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n)
{
    int idx;
    if (!rb_obj_is_kind_of(olemethod, cWIN32OLE_METHOD)) {
        rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE_METHOD object");
    }
    idx = FIX2INT(n);
    return oleparam_ole_param(self, olemethod, idx);
}

Public Instance Methods

WIN32OLE_PARAM#default click to toggle source

Returns default value. If the default value does not exist, this method returns nil.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
method.params.each do |param|
  if param.default
    puts "#{param.name} (= #{param.default})"
  else
    puts "#{param}"
  end
end

The above script result is following:
    Filename
    FileFormat
    Password
    WriteResPassword
    ReadOnlyRecommended
    CreateBackup
    AccessMode (= 1)
    ConflictResolution
    AddToMru
    TextCodepage
    TextVisualLayout

static VALUE foleparam_default(VALUE self)
{
    struct oleparamdata *pparam;
    Data_Get_Struct(self, struct oleparamdata, pparam);
    return ole_param_default(pparam->pTypeInfo, pparam->method_index,
                             pparam->index);
}
WIN32OLE_PARAM#input? click to toggle source

Returns true if the parameter is input.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
param1 = method.params[0]
puts param1.input? # => true

static VALUE foleparam_input(VALUE self)
{
    struct oleparamdata *pparam;
    Data_Get_Struct(self, struct oleparamdata, pparam);
    return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
                               pparam->index, PARAMFLAG_FIN);
}
WIN32OLE_PARAM#inspect → String click to toggle source

Returns the parameter name with class name. If the parameter has default value, then returns name=value string with class name.

static VALUE
foleparam_inspect(VALUE self)
{
    VALUE detail = foleparam_name(self);
    VALUE defval = foleparam_default(self);
    if (defval != Qnil) {
        rb_str_cat2(detail, "=");
        rb_str_concat(detail, rb_funcall(defval, rb_intern("inspect"), 0));
    }
    return make_inspect("WIN32OLE_PARAM", detail);
}
WIN32OLE_PARAM#name click to toggle source

Returns name.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
param1 = method.params[0]
puts param1.name # => Filename

static VALUE
foleparam_name(VALUE self)
{
    return rb_ivar_get(self, rb_intern("name"));
}
Also aliased as: to_s
WIN32OLE_PARAM#ole_type click to toggle source

Returns OLE type of WIN32OLE_PARAM object(parameter of OLE method).

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
param1 = method.params[0]
puts param1.ole_type # => VARIANT

static VALUE
foleparam_ole_type(VALUE self)
{
    struct oleparamdata *pparam;
    Data_Get_Struct(self, struct oleparamdata, pparam);
    return ole_param_ole_type(pparam->pTypeInfo, pparam->method_index,
                              pparam->index);
}
WIN32OLE_PARAM#ole_type_detail click to toggle source

Returns detail information of type of argument.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'IWorksheetFunction')
method = WIN32OLE_METHOD.new(tobj, 'SumIf')
param1 = method.params[0]
p param1.ole_type_detail # => ["PTR", "USERDEFINED", "Range"]

static VALUE
foleparam_ole_type_detail(VALUE self)
{
    struct oleparamdata *pparam;
    Data_Get_Struct(self, struct oleparamdata, pparam);
    return ole_param_ole_type_detail(pparam->pTypeInfo, pparam->method_index,
                                     pparam->index);
}
WIN32OLE_PARAM#optional? click to toggle source

Returns true if argument is optional.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
param1 = method.params[0]
puts "#{param1.name} #{param1.optional?}" # => Filename true

static VALUE foleparam_optional(VALUE self)
{
    struct oleparamdata *pparam;
    Data_Get_Struct(self, struct oleparamdata, pparam);
    return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
                               pparam->index, PARAMFLAG_FOPT);
}
WIN32OLE#output? click to toggle source

Returns true if argument is output.

tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'DWebBrowserEvents')
method = WIN32OLE_METHOD.new(tobj, 'NewWindow')
method.params.each do |param|
  puts "#{param.name} #{param.output?}"
end

The result of above script is following:
  URL false
  Flags false
  TargetFrameName false
  PostData false
  Headers false
  Processed true

static VALUE foleparam_output(VALUE self)
{
    struct oleparamdata *pparam;
    Data_Get_Struct(self, struct oleparamdata, pparam);
    return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
                               pparam->index, PARAMFLAG_FOUT);
}
WIN32OLE_PARAM#retval? click to toggle source

Returns true if argument is return value.

tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library',
                         'DirectPlayLobbyConnection')
method = WIN32OLE_METHOD.new(tobj, 'GetPlayerShortName')
param = method.params[0]
puts "#{param.name} #{param.retval?}"  # => name true

static VALUE foleparam_retval(VALUE self)
{
    struct oleparamdata *pparam;
    Data_Get_Struct(self, struct oleparamdata, pparam);
    return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
                               pparam->index, PARAMFLAG_FRETVAL);
}
to_s() click to toggle source
Alias for: name


class WIN32OLE_TYPE - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WIN32OLE_TYPE

WIN32OLE_TYPE objects represent OLE type libarary information.

In Files

  • ext/win32ole/win32ole.c

Parent

Object

Public Class Methods

new(typelib, ole_class) → WIN32OLE_TYPE object click to toggle source

Returns a new WIN32OLE_TYPE object. The first argument typelib specifies OLE type library name. The second argument specifies OLE class name.

WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
    # => WIN32OLE_TYPE object of Application class of Excel.

static VALUE
foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass)
{
    VALUE file;
    OLECHAR * pbuf;
    ITypeLib *pTypeLib;
    HRESULT hr;

    SafeStringValue(oleclass);
    SafeStringValue(typelib);
    file = typelib_file(typelib);
    if (file == Qnil) {
        file = typelib;
    }
    pbuf = ole_vstr2wc(file);
    hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
    if (FAILED(hr))
        ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
    SysFreeString(pbuf);
    if (oleclass_from_typelib(self, pTypeLib, oleclass) == Qfalse) {
        OLE_RELEASE(pTypeLib);
        rb_raise(eWIN32OLERuntimeError, "not found `%s` in `%s`",
                 StringValuePtr(oleclass), StringValuePtr(typelib));
    }
    OLE_RELEASE(pTypeLib);
    return self;
}
ole_classes(typelib) click to toggle source

Returns array of WIN32OLE_TYPE objects defined by the typelib type library. This method will be OBSOLETE. Use WIN32OLE_TYPELIB.new.::ole_classes instead.

static VALUE
foletype_s_ole_classes(VALUE self, VALUE typelib)
{
    VALUE obj;

    /*
    rb_warn("%s is obsolete; use %s instead.",
            "WIN32OLE_TYPE.ole_classes",
            "WIN32OLE_TYPELIB.new(typelib).ole_types");
    */
    obj = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("new"), 1, typelib);
    return rb_funcall(obj, rb_intern("ole_types"), 0);
}
progids click to toggle source

Returns array of ProgID.

static VALUE
foletype_s_progids(VALUE self)
{
    HKEY hclsids, hclsid;
    DWORD i;
    LONG err;
    VALUE clsid;
    VALUE v = rb_str_new2("");
    VALUE progids = rb_ary_new();

    err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hclsids);
    if(err != ERROR_SUCCESS) {
        return progids;
    }
    for(i = 0; ; i++) {
        clsid = reg_enum_key(hclsids, i);
        if (clsid == Qnil)
            break;
        err = reg_open_vkey(hclsids, clsid, &hclsid);
        if (err != ERROR_SUCCESS)
            continue;
        if ((v = reg_get_val2(hclsid, "ProgID")) != Qnil)
            rb_ary_push(progids, v);
        if ((v = reg_get_val2(hclsid, "VersionIndependentProgID")) != Qnil)
            rb_ary_push(progids, v);
        RegCloseKey(hclsid);
    }
    RegCloseKey(hclsids);
    return progids;
}
typelibs click to toggle source

Returns array of type libraries. This method will be OBSOLETE. Use WIN32OLE_TYPELIB.typelibs.collect{|t| t.name} instead.

static VALUE
foletype_s_typelibs(VALUE self)
{
    /*
    rb_warn("%s is obsolete. use %s instead.",
            "WIN32OLE_TYPE.typelibs",
            "WIN32OLE_TYPELIB.typelibs.collect{t|t.name}");
    */
    return rb_eval_string("WIN32OLE_TYPELIB.typelibs.collect{|t|t.name}");
}

Public Instance Methods

WIN32OLE_TYPE#default_event_sources click to toggle source

Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE object and having IMPLTYPEFLAG_FSOURCE and IMPLTYPEFLAG_FDEFAULT.

tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
p tobj.default_event_sources  # => [#<WIN32OLE_TYPE:DWebBrowserEvents2>]

static VALUE
foletype_default_event_sources(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT);
}
WIN32OLE_TYPE#default_ole_types click to toggle source

Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE object and having IMPLTYPEFLAG_FDEFAULT.

tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
p tobj.default_ole_types
# => [#<WIN32OLE_TYPE:IWebBrowser2>, #<WIN32OLE_TYPE:DWebBrowserEvents2>]

static VALUE
foletype_default_ole_types(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FDEFAULT);
}
WIN32OLE_TYPE#guid #→ GUID click to toggle source

Returns GUID.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
puts tobj.guid  # => {00024500-0000-0000-C000-000000000046}

static VALUE
foletype_guid(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_guid(ptype->pTypeInfo);
}
WIN32OLE_TYPE#helpcontext click to toggle source

Returns helpcontext. If helpcontext is not found, then returns nil.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
puts tobj.helpfile # => 131185

static VALUE
foletype_helpcontext(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_helpcontext(ptype->pTypeInfo);
}
WIN32OLE_TYPE#helpfile click to toggle source

Returns helpfile path. If helpfile is not found, then returns nil.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
puts tobj.helpfile # => C:\...\VBAXL9.CHM

static VALUE
foletype_helpfile(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_helpfile(ptype->pTypeInfo);
}
WIN32OLE_TYPE#helpstring #→ help string. click to toggle source

Returns help string.

tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser')
puts tobj.helpstring # => Web Browser interface

static VALUE
foletype_helpstring(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_helpstring(ptype->pTypeInfo);
}
WIN32OLE_TYPE#implemented_ole_types click to toggle source

Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE object.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
p tobj.implemented_ole_types # => [_Worksheet, DocEvents]

static VALUE
foletype_impl_ole_types(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_impl_ole_types(ptype->pTypeInfo, 0);
}
WIN32OLE_TYPE#inspect → String click to toggle source

Returns the type name with class name.

ie = WIN32OLE.new('InternetExplorer.Application')
ie.ole_type.inspect => #<WIN32OLE_TYPE:IWebBrowser2>

static VALUE
foletype_inspect(VALUE self)
{
    return default_inspect(self, "WIN32OLE_TYPE");
}
WIN32OLE_TYPE#major_version click to toggle source

Returns major version.

tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
puts tobj.major_version # => 8

static VALUE
foletype_major_version(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_major_version(ptype->pTypeInfo);
}
WIN32OLE_TYPE#minor_version #→ OLE minor version click to toggle source

Returns minor version.

tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
puts tobj.minor_version # => 2

static VALUE
foletype_minor_version(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_minor_version(ptype->pTypeInfo);
}
WIN32OLE_TYPE#name #→ OLE type name click to toggle source

Returns OLE type name.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
puts tobj.name  # => Application

static VALUE
foletype_name(VALUE self)
{
    return rb_ivar_get(self, rb_intern("name"));
}
Also aliased as: to_s
WIN32OLE_TYPE#ole_methods # the array of WIN32OLE_METHOD objects. click to toggle source

Returns array of WIN32OLE_METHOD objects which represent OLE method defined in OLE type library.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
methods = tobj.ole_methods.collect{|m|
  m.name
}
# => ['Activate', 'Copy', 'Delete',....]

static VALUE
foletype_methods(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_methods_from_typeinfo(ptype->pTypeInfo, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
}
WIN32OLE_TYPE#ole_type #→ OLE type string. click to toggle source

returns type of OLE class.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
puts tobj.ole_type  # => Class

static VALUE
foletype_ole_type(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_ole_type(ptype->pTypeInfo);
}
WIN32OLE_TYPE#ole_typelib click to toggle source

Returns the WIN32OLE_TYPELIB object which is including the WIN32OLE_TYPE object. If it is not found, then returns nil.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
puts tobj.ole_typelib # => 'Microsoft Excel 9.0 Object Library'

static VALUE
foletype_ole_typelib(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_typelib_from_itypeinfo(ptype->pTypeInfo);
}
WIN32OLE_TYPE#progid #→ ProgID click to toggle source

Returns ProgID if it exists. If not found, then returns nil.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
puts tobj.progid  # =>   Excel.Application.9

static VALUE
foletype_progid(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_progid(ptype->pTypeInfo);
}
WIN32OLE_TYPE#source_ole_types click to toggle source

Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE object and having IMPLTYPEFLAG_FSOURCE.

tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
p tobj.source_ole_types
# => [#<WIN32OLE_TYPE:DWebBrowserEvents2>, #<WIN32OLE_TYPE:DWebBrowserEvents>]

static VALUE
foletype_source_ole_types(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FSOURCE);
}
WIN32OLE_TYPE#src_type #→ OLE source class click to toggle source

Returns source class when the OLE class is 'Alias'.

tobj =  WIN32OLE_TYPE.new('Microsoft Office 9.0 Object Library', 'MsoRGBType')
puts tobj.src_type # => I4

static VALUE
foletype_src_type(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_src_type(ptype->pTypeInfo);
}
to_s() click to toggle source
Alias for: name
WIN32OLE_TYPE#typekind #→ number of type. click to toggle source

Returns number which represents type.

tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
puts tobj.typekind # => 4

static VALUE
foletype_typekind(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_typekind(ptype->pTypeInfo);
}
WIN32OLE_TYPE#variables click to toggle source

Returns array of WIN32OLE_VARIABLE objects which represent variables defined in OLE class.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
vars = tobj.variables
vars.each do |v|
  puts "#{v.name} = #{v.value}"
end

The result of above sample script is follows:
  xlChart = -4109
  xlDialogSheet = -4116
  xlExcel4IntlMacroSheet = 4
  xlExcel4MacroSheet = 3
  xlWorksheet = -4167

static VALUE
foletype_variables(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_variables(ptype->pTypeInfo);
}
WIN32OLE_TYPE#visible #→ true or false click to toggle source

Returns true if the OLE class is public.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
puts tobj.visible  # => true

static VALUE
foletype_visible(VALUE self)
{
    struct oletypedata *ptype;
    Data_Get_Struct(self, struct oletypedata, ptype);
    return ole_type_visible(ptype->pTypeInfo);
}


class WIN32OLE_TYPELIB - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WIN32OLE_TYPELIB

WIN32OLE_TYPELIB objects represent OLE tyblib information.

In Files

  • ext/win32ole/win32ole.c

Parent

Object

Public Class Methods

new(typelib [, version1, version2]) → WIN32OLE_TYPELIB object click to toggle source

Returns a new WIN32OLE_TYPELIB object.

The first argument typelib specifies OLE type library name or GUID or OLE library file. The second argument is major version or version of the type library. The third argument is minor version. The second argument and third argument are optional. If the first argument is type library name, then the second and third argument are ignored.

tlib1 = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
tlib2 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}')
tlib3 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1.3)
tlib4 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1, 3)
tlib5 = WIN32OLE_TYPELIB.new("C:\\WINNT\\SYSTEM32\\SHELL32.DLL")
puts tlib1.name  # -> 'Microsoft Excel 9.0 Object Library'
puts tlib2.name  # -> 'Microsoft Excel 9.0 Object Library'
puts tlib3.name  # -> 'Microsoft Excel 9.0 Object Library'
puts tlib4.name  # -> 'Microsoft Excel 9.0 Object Library'
puts tlib5.name  # -> 'Microsoft Shell Controls And Automation'
static VALUE
foletypelib_initialize(VALUE self, VALUE args)
{
    VALUE found = Qfalse;
    VALUE typelib = Qnil;
    int len = 0;
    OLECHAR * pbuf;
    ITypeLib *pTypeLib;
    HRESULT hr = S_OK;

    len = RARRAY_LEN(args);
    if (len < 1 || len > 3) {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
    }

    typelib = rb_ary_entry(args, 0);

    SafeStringValue(typelib);

    found = oletypelib_search_registry(self, typelib);
    if (found == Qfalse) {
        found = oletypelib_search_registry2(self, args);
    }
    if (found == Qfalse) {
        pbuf = ole_vstr2wc(typelib);
        hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
        SysFreeString(pbuf);
        if (SUCCEEDED(hr)) {
            found = Qtrue;
            oletypelib_set_member(self, pTypeLib);
        }
    }

    if (found == Qfalse) {
        rb_raise(eWIN32OLERuntimeError, "not found type library `%s`",
                 StringValuePtr(typelib));
    }
    return self;
}
typelibs click to toggle source

Returns the array of WIN32OLE_TYPELIB object.

tlibs = WIN32OLE_TYPELIB.typelibs
static VALUE
foletypelib_s_typelibs(VALUE self)
{
    HKEY htypelib, hguid;
    DWORD i, j;
    LONG err;
    VALUE guid;
    VALUE version;
    VALUE name = Qnil;
    VALUE typelibs = rb_ary_new();
    VALUE typelib = Qnil;
    HRESULT hr;
    ITypeLib *pTypeLib;

    err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
    if(err != ERROR_SUCCESS) {
        return typelibs;
    }
    for(i = 0; ; i++) {
        guid = reg_enum_key(htypelib, i);
        if (guid == Qnil)
            break;
        err = reg_open_vkey(htypelib, guid, &hguid);
        if (err != ERROR_SUCCESS)
            continue;
        for(j = 0; ; j++) {
            version = reg_enum_key(hguid, j);
            if (version == Qnil)
                break;
            if ( (name = reg_get_val2(hguid, StringValuePtr(version))) != Qnil ) {
                hr = oletypelib_from_guid(guid, version, &pTypeLib);
                if (SUCCEEDED(hr)) {
                    typelib = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("allocate"), 0);
                    oletypelib_set_member(typelib, pTypeLib);
                    rb_ary_push(typelibs, typelib);
                }
            }
        }
        RegCloseKey(hguid);
    }
    RegCloseKey(htypelib);
    return typelibs;
}

Public Instance Methods

WIN32OLE_TYPELIB#guid → The guid string. click to toggle source

Returns guid string which specifies type library.

tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
guid = tlib.guid # -> '{00020813-0000-0000-C000-000000000046}'
static VALUE
foletypelib_guid(VALUE self)
{
    ITypeLib *pTypeLib;
    OLECHAR bstr[80];
    VALUE guid = Qnil;
    int len;
    TLIBATTR *pTLibAttr;

    pTypeLib = oletypelib_get_typelib(self);
    oletypelib_get_libattr(pTypeLib, &pTLibAttr);
    len = StringFromGUID2(&pTLibAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
    if (len > 3) {
        guid = ole_wc2vstr(bstr, FALSE);
    }
    pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
    return guid;
}
WIN32OLE_TYPELIB#inspect → String click to toggle source

Returns the type library name with class name.

tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
tlib.inspect # => "<#WIN32OLE_TYPELIB:Microsoft Excel 9.0 Object Library>"

static VALUE
foletypelib_inspect(VALUE self)
{
    return default_inspect(self, "WIN32OLE_TYPELIB");
}
WIN32OLE_TYPELIB#library_name click to toggle source

Returns library name. If the method fails to access library name, WIN32OLERuntimeError is raised.

tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
tlib.library_name # => Excel

static VALUE
foletypelib_library_name(VALUE self)
{
    HRESULT hr;
    ITypeLib *pTypeLib = NULL;
    VALUE libname = Qnil;
    BSTR bstr;

    pTypeLib = oletypelib_get_typelib(self);
    hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
                                            &bstr, NULL, NULL, NULL);
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "failed to get library name");
    }
    libname = WC2VSTR(bstr);
    return libname;
}
WIN32OLE_TYPELIB#major_version → The type library major version. click to toggle source

Returns the type library major version.

tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
puts tlib.major_version # -> 1
static VALUE
foletypelib_major_version(VALUE self)
{
    TLIBATTR *pTLibAttr;
    VALUE major;
    ITypeLib *pTypeLib;
    pTypeLib = oletypelib_get_typelib(self);
    oletypelib_get_libattr(pTypeLib, &pTLibAttr);

    major =  INT2NUM(pTLibAttr->wMajorVerNum);
    pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
    return major;
}
WIN32OLE_TYPELIB#minor_version → The type library minor version. click to toggle source

Returns the type library minor version.

tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
puts tlib.minor_version # -> 3
static VALUE
foletypelib_minor_version(VALUE self)
{
    TLIBATTR *pTLibAttr;
    VALUE minor;
    ITypeLib *pTypeLib;
    pTypeLib = oletypelib_get_typelib(self);
    oletypelib_get_libattr(pTypeLib, &pTLibAttr);
    minor =  INT2NUM(pTLibAttr->wMinorVerNum);
    pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
    return minor;
}
WIN32OLE_TYPELIB#name → The type library name click to toggle source

Returns the type library name.

tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
name = tlib.name # -> 'Microsoft Excel 9.0 Object Library'
static VALUE
foletypelib_name(VALUE self)
{
    ITypeLib *pTypeLib;
    HRESULT hr;
    BSTR bstr;
    VALUE name;
    pTypeLib = oletypelib_get_typelib(self);
    hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
                                            NULL, &bstr, NULL, NULL);

    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "failed to get name from ITypeLib");
    }
    name = WC2VSTR(bstr);
    return rb_enc_str_new(StringValuePtr(name), strlen(StringValuePtr(name)), cWIN32OLE_enc);
}
Also aliased as: to_s
ole_classes() click to toggle source
Alias for: ole_types
WIN32OLE_TYPELIB#ole_types → The array of WIN32OLE_TYPE object included the type library. click to toggle source

Returns the type library file path.

tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
classes = tlib.ole_types.collect{|k| k.name} # -> ['AddIn', 'AddIns' ...]

static VALUE
foletypelib_ole_types(VALUE self)
{
    ITypeLib *pTypeLib = NULL;
    VALUE classes = rb_ary_new();
    pTypeLib = oletypelib_get_typelib(self);
    ole_types_from_typelib(pTypeLib, classes);
    return classes;
}
Also aliased as: ole_classes
WIN32OLE_TYPELIB#path → The type library file path. click to toggle source

Returns the type library file path.

tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
puts tlib.path #-> 'C:\...\EXCEL9.OLB'
static VALUE
foletypelib_path(VALUE self)
{
    TLIBATTR *pTLibAttr;
    HRESULT hr = S_OK;
    BSTR bstr;
    LCID lcid = cWIN32OLE_lcid;
    VALUE path;
    ITypeLib *pTypeLib;

    pTypeLib = oletypelib_get_typelib(self);
    oletypelib_get_libattr(pTypeLib, &pTLibAttr);
    hr = QueryPathOfRegTypeLib(&pTLibAttr->guid,
                               pTLibAttr->wMajorVerNum,
                               pTLibAttr->wMinorVerNum,
                               lcid,
                               &bstr);
    if (FAILED(hr)) {
        pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
        ole_raise(hr, eWIN32OLERuntimeError, "failed to QueryPathOfRegTypeTypeLib");
    }

    pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
    path = WC2VSTR(bstr);
    return rb_enc_str_new(StringValuePtr(path), strlen(StringValuePtr(path)), cWIN32OLE_enc);
}
to_s() click to toggle source
Alias for: name
WIN32OLE_TYPELIB#version → The type library version. click to toggle source

Returns the type library version.

tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
puts tlib.version #-> 1.3
static VALUE
foletypelib_version(VALUE self)
{
    TLIBATTR *pTLibAttr;
    VALUE major;
    VALUE minor;
    ITypeLib *pTypeLib;

    pTypeLib = oletypelib_get_typelib(self);
    oletypelib_get_libattr(pTypeLib, &pTLibAttr);
    major = INT2NUM(pTLibAttr->wMajorVerNum);
    minor = INT2NUM(pTLibAttr->wMinorVerNum);
    pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
    return rb_Float(make_version_str(major, minor));
}
WIN32OLE_TYPELIB#visible? click to toggle source

Returns true if the type library information is not hidden. If wLibFlags of TLIBATTR is 0 or LIBFLAG_FRESTRICTED or LIBFLAG_FHIDDEN, the method returns false, otherwise, returns true. If the method fails to access the TLIBATTR information, then WIN32OLERuntimeError is raised.

tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
tlib.visible? # => true

static VALUE
foletypelib_visible(VALUE self)
{
    ITypeLib *pTypeLib = NULL;
    VALUE visible = Qtrue;
    TLIBATTR *pTLibAttr;

    pTypeLib = oletypelib_get_typelib(self);
    oletypelib_get_libattr(pTypeLib, &pTLibAttr);

    if ((pTLibAttr->wLibFlags == 0) ||
        (pTLibAttr->wLibFlags & LIBFLAG_FRESTRICTED) ||
        (pTLibAttr->wLibFlags & LIBFLAG_FHIDDEN)) {
        visible = Qfalse;
    }
    pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
    return visible;
}


class WIN32OLE_VARIABLE - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WIN32OLE_VARIABLE

WIN32OLE_VARIABLE objects represent OLE variable information.

In Files

  • ext/win32ole/win32ole.c

Parent

Object

Public Instance Methods

WIN32OLE_VARIABLE#inspect → String click to toggle source

Returns the OLE variable name and the value with class name.

static VALUE
folevariable_inspect(VALUE self)
{
    VALUE detail = rb_funcall(self, rb_intern("to_s"), 0);
    rb_str_cat2(detail, "=");
    rb_str_concat(detail, rb_funcall(rb_funcall(self, rb_intern("value"), 0), rb_intern("inspect"), 0));
    return make_inspect("WIN32OLE_VARIABLE", detail);
}
WIN32OLE_VARIABLE#name click to toggle source

Returns the name of variable.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
variables = tobj.variables
variables.each do |variable|
  puts "#{variable.name}"
end

The result of above script is following:
  xlChart
  xlDialogSheet
  xlExcel4IntlMacroSheet
  xlExcel4MacroSheet
  xlWorksheet

static VALUE
folevariable_name(VALUE self)
{
    return rb_ivar_get(self, rb_intern("name"));
}
Also aliased as: to_s
WIN32OLE_VARIABLE#ole_type click to toggle source

Returns OLE type string.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
variables = tobj.variables
variables.each do |variable|
  puts "#{variable.ole_type} #{variable.name}"
end

The result of above script is following:
  INT xlChart
  INT xlDialogSheet
  INT xlExcel4IntlMacroSheet
  INT xlExcel4MacroSheet
  INT xlWorksheet

static VALUE
folevariable_ole_type(VALUE self)
{
    struct olevariabledata *pvar;
    Data_Get_Struct(self, struct olevariabledata, pvar);
    return ole_variable_ole_type(pvar->pTypeInfo, pvar->index);
}
WIN32OLE_VARIABLE#ole_type_detail click to toggle source

Returns detail information of type. The information is array of type.

tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', 'D3DCLIPSTATUS')
variable = tobj.variables.find {|variable| variable.name == 'lFlags'}
tdetail  = variable.ole_type_detail
p tdetail # => ["USERDEFINED", "CONST_D3DCLIPSTATUSFLAGS"]

static VALUE
folevariable_ole_type_detail(VALUE self)
{
    struct olevariabledata *pvar;
    Data_Get_Struct(self, struct olevariabledata, pvar);
    return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index);
}
to_s() click to toggle source
Alias for: name
WIN32OLE_VARIABLE#value click to toggle source

Returns value if value is exists. If the value does not exist, this method returns nil.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
variables = tobj.variables
variables.each do |variable|
  puts "#{variable.name} #{variable.value}"
end

The result of above script is following:
  xlChart = -4109
  xlDialogSheet = -4116
  xlExcel4IntlMacroSheet = 4
  xlExcel4MacroSheet = 3
  xlWorksheet = -4167

static VALUE
folevariable_value(VALUE self)
{
    struct olevariabledata *pvar;
    Data_Get_Struct(self, struct olevariabledata, pvar);
    return ole_variable_value(pvar->pTypeInfo, pvar->index);
}
WIN32OLE_VARIABLE#variable_kind click to toggle source

Returns variable kind string.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
variables = tobj.variables
variables.each do |variable|
  puts "#{variable.name} #{variable.variable_kind}"
end

The result of above script is following:
  xlChart CONSTANT
  xlDialogSheet CONSTANT
  xlExcel4IntlMacroSheet CONSTANT
  xlExcel4MacroSheet CONSTANT
  xlWorksheet CONSTANT

static VALUE
folevariable_variable_kind(VALUE self)
{
    struct olevariabledata *pvar;
    Data_Get_Struct(self, struct olevariabledata, pvar);
    return ole_variable_kind(pvar->pTypeInfo, pvar->index);
}
WIN32OLE_VARIABLE#varkind click to toggle source

Returns the number which represents variable kind.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
variables = tobj.variables
variables.each do |variable|
  puts "#{variable.name} #{variable.varkind}"
end

The result of above script is following:
   xlChart 2
   xlDialogSheet 2
   xlExcel4IntlMacroSheet 2
   xlExcel4MacroSheet 2
   xlWorksheet 2

static VALUE
folevariable_varkind(VALUE self)
{
    struct olevariabledata *pvar;
    Data_Get_Struct(self, struct olevariabledata, pvar);
    return ole_variable_varkind(pvar->pTypeInfo, pvar->index);
}
WIN32OLE_VARIABLE#visible? click to toggle source

Returns true if the variable is public.

tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
variables = tobj.variables
variables.each do |variable|
  puts "#{variable.name} #{variable.visible?}"
end

The result of above script is following:
  xlChart true
  xlDialogSheet true
  xlExcel4IntlMacroSheet true
  xlExcel4MacroSheet true
  xlWorksheet true

static VALUE
folevariable_visible(VALUE self)
{
    struct olevariabledata *pvar;
    Data_Get_Struct(self, struct olevariabledata, pvar);
    return ole_variable_visible(pvar->pTypeInfo, pvar->index);
}


class WIN32OLE_VARIANT - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WIN32OLE_VARIANT

In Files

  • ext/win32ole/win32ole.c

Parent

Object

Constants

Empty
Nothing
Null

Public Class Methods

array(ary, vt) click to toggle source

Returns Ruby object wrapping OLE variant whose variant type is VT_ARRAY. The first argument should be Array object which specifies dimensions and each size of dimensions of OLE array. The second argument specifies variant type of the element of OLE array.

The following create 2 dimensions OLE array. The first dimensions size is 3, and the second is 4.

ole_ary = WIN32OLE_VARIANT.array([3,4], VT_I4)
ruby_ary = ole_ary.value # => [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

static VALUE
folevariant_s_array(VALUE klass, VALUE elems, VALUE vvt)
{
    VALUE obj = Qnil;
    VARTYPE vt;
    struct olevariantdata *pvar;
    SAFEARRAYBOUND *psab = NULL;
    SAFEARRAY *psa = NULL;
    UINT dim = 0;
    UINT i = 0;

    ole_initialize();

    vt = NUM2UINT(vvt);
    vt = (vt | VT_ARRAY);
    Check_Type(elems, T_ARRAY);
    obj = folevariant_s_allocate(klass);

    Data_Get_Struct(obj, struct olevariantdata, pvar);
    dim = RARRAY_LEN(elems);

    psab = ALLOC_N(SAFEARRAYBOUND, dim);

    if(!psab) {
        rb_raise(rb_eRuntimeError, "memory allocation error");
    }

    for (i = 0; i < dim; i++) {
        psab[i].cElements = FIX2INT(rb_ary_entry(elems, i));
        psab[i].lLbound = 0;
    }

    psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab);
    if (psa == NULL) {
        if (psab) free(psab);
        rb_raise(rb_eRuntimeError, "memory allocation error(SafeArrayCreate)");
    }

    V_VT(&(pvar->var)) = vt;
    if (vt & VT_BYREF) {
        V_VT(&(pvar->realvar)) = (vt & ~VT_BYREF);
        V_ARRAY(&(pvar->realvar)) = psa;
        V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
    } else {
        V_ARRAY(&(pvar->var)) = psa;
    }
    if (psab) free(psab);
    return obj;
}
new(val, vartype) #→ WIN32OLE_VARIANT object. click to toggle source

Returns Ruby object wrapping OLE variant. The first argument specifies Ruby object to convert OLE variant variable. The second argument specifies VARIANT type. In some situation, you need the WIN32OLE_VARIANT object to pass OLE method

shell = WIN32OLE.new("Shell.Application")
folder = shell.NameSpace("C:\\Windows")
item = folder.ParseName("tmp.txt")
# You can't use Ruby String object to call FolderItem.InvokeVerb.
# Instead, you have to use WIN32OLE_VARIANT object to call the method.
shortcut = WIN32OLE_VARIANT.new("Create Shortcut(\&S)")
item.invokeVerb(shortcut)
static VALUE
folevariant_initialize(VALUE self, VALUE args)
{
    int len = 0;
    VARIANT var;
    VALUE val;
    VALUE vvt;
    VARTYPE vt;
    struct olevariantdata *pvar;

    len = RARRAY_LEN(args);
    if (len < 1 || len > 3) {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
    }
    VariantInit(&var);
    val = rb_ary_entry(args, 0);

    if(!rb_obj_is_kind_of(val, cWIN32OLE) &&
       !rb_obj_is_kind_of(val, cWIN32OLE_VARIANT) &&
       !rb_obj_is_kind_of(val, rb_cTime)) {
        switch (TYPE(val)) {
        case T_ARRAY:
        case T_STRING:
        case T_FIXNUM:
        case T_BIGNUM:
        case T_FLOAT:
        case T_TRUE:
        case T_FALSE:
        case T_NIL:
            break;
        default:
            rb_raise(rb_eTypeError, "can not convert WIN32OLE_VARIANT from type %s",
                     rb_obj_classname(val));
        }
    }

    Data_Get_Struct(self, struct olevariantdata, pvar);
    if (len == 1) {
        ole_val2variant(val, &(pvar->var));
    } else {
        vvt = rb_ary_entry(args, 1);
        vt = NUM2INT(vvt);
        ole_val2olevariantdata(val, vt, pvar);
    }
    vt = V_VT(&pvar->var);
    return self;
}

Public Instance Methods

WIN32OLE_VARIANT[i,j,...] #→ element of OLE array. click to toggle source

Returns the element of WIN32OLE_VARIANT object(OLE array). This method is available only when the variant type of WIN32OLE_VARIANT object is VT_ARRAY.

REMARK:

The all indicies should be 0 or natural number and
lower than or equal to max indicies.
(This point is different with Ruby Array indicies.)

obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]])
p obj[0,0] # => 1
p obj[1,0] # => 4
p obj[2,0] # => WIN32OLERuntimeError
p obj[0, -1] # => WIN32OLERuntimeError

static VALUE
folevariant_ary_aref(int argc, VALUE *argv, VALUE self)
{
    struct olevariantdata *pvar;
    SAFEARRAY *psa;
    VALUE val = Qnil;
    VARIANT variant;
    long *pid;
    HRESULT hr;

    Data_Get_Struct(self, struct olevariantdata, pvar);
    if (!V_ISARRAY(&(pvar->var))) {
        rb_raise(eWIN32OLERuntimeError,
                 "`[]' is not available for this variant type object");
    }
    psa = get_locked_safe_array(self);
    if (psa == NULL) {
        return val;
    }

    pid = ary2safe_array_index(argc, argv, psa);

    VariantInit(&variant);
    V_VT(&variant) = (V_VT(&(pvar->var)) & ~VT_ARRAY) | VT_BYREF;
    hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant));
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPtrOfIndex");
    }
    val = ole_variant2val(&variant);

    unlock_safe_array(psa);
    if (pid) free(pid);
    return val;
}
WIN32OLE_VARIANT[i,j,...] = val #→ set the element of OLE array click to toggle source

Set the element of WIN32OLE_VARIANT object(OLE array) to val. This method is available only when the variant type of WIN32OLE_VARIANT object is VT_ARRAY.

REMARK:

The all indicies should be 0 or natural number and
lower than or equal to max indicies.
(This point is different with Ruby Array indicies.)

obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]])
obj[0,0] = 7
obj[1,0] = 8
p obj.value # => [[7,2,3], [8,5,6]]
obj[2,0] = 9 # => WIN32OLERuntimeError
obj[0, -1] = 9 # => WIN32OLERuntimeError

static VALUE
folevariant_ary_aset(int argc, VALUE *argv, VALUE self)
{
    struct olevariantdata *pvar;
    SAFEARRAY *psa;
    VARIANT var;
    VARTYPE vt;
    long *pid;
    HRESULT hr;
    VOID *p = NULL;

    Data_Get_Struct(self, struct olevariantdata, pvar);
    if (!V_ISARRAY(&(pvar->var))) {
        rb_raise(eWIN32OLERuntimeError,
                 "`[]' is not available for this variant type object");
    }
    psa = get_locked_safe_array(self);
    if (psa == NULL) {
        rb_raise(rb_eRuntimeError, "failed to get SafeArray pointer");
    }

    pid = ary2safe_array_index(argc-1, argv, psa);

    VariantInit(&var);
    vt = (V_VT(&(pvar->var)) & ~VT_ARRAY);
    p = val2variant_ptr(argv[argc-1], &var, vt);
    if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) ||
        (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) {
        rb_raise(eWIN32OLERuntimeError, "argument does not have IDispatch or IUnknown Interface");
    }
    hr = SafeArrayPutElement(psa, pid, p);
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPutElement");
    }

    unlock_safe_array(psa);
    if (pid) free(pid);
    return argv[argc-1];
}
value #→ Ruby object. click to toggle source

Returns Ruby object value from OLE variant.

obj = WIN32OLE_VARIANT.new(1, WIN32OLE::VARIANT::VT_BSTR)
obj.value # => "1" (not Fixnum object, but String object "1")

static VALUE
folevariant_value(VALUE self)
{
    struct olevariantdata *pvar;
    VALUE val = Qnil;
    VARTYPE vt;
    int dim;
    SAFEARRAY *psa;
    Data_Get_Struct(self, struct olevariantdata, pvar);

    val = ole_variant2val(&(pvar->var));
    vt = V_VT(&(pvar->var));

    if ((vt & ~VT_BYREF) == (VT_UI1|VT_ARRAY)) {
        if (vt & VT_BYREF) {
            psa = *V_ARRAYREF(&(pvar->var));
        } else {
            psa  = V_ARRAY(&(pvar->var));
        }
        if (!psa) {
            return val;
        }
        dim = SafeArrayGetDim(psa);
        if (dim == 1) {
            val = rb_funcall(val, rb_intern("pack"), 1, rb_str_new2("C*"));
        }
    }
    return val;
}
value = val #→ set WIN32OLE_VARIANT value to val. click to toggle source

Sets variant value to val. If the val type does not match variant value type(vartype), then val is changed to match variant value type(vartype) before setting val. Thie method is not available when vartype is VT_ARRAY(except VT_UI1|VT_ARRAY). If the vartype is VT_UI1|VT_ARRAY, the val should be String object.

obj = WIN32OLE_VARIANT.new(1) # obj.vartype is WIN32OLE::VARIANT::VT_I4
obj.value = 3.2 # 3.2 is changed to 3 when setting value.
p obj.value # => 3

static VALUE
folevariant_set_value(VALUE self, VALUE val)
{
    struct olevariantdata *pvar;
    VARTYPE vt;
    Data_Get_Struct(self, struct olevariantdata, pvar);
    vt = V_VT(&(pvar->var));
    if (V_ISARRAY(&(pvar->var)) && ((vt & ~VT_BYREF) != (VT_UI1|VT_ARRAY) || TYPE(val) != T_STRING)) {
        rb_raise(eWIN32OLERuntimeError,
                 "`value=' is not available for this variant type object");
    }
    ole_val2olevariantdata(val, vt, pvar);
    return Qnil;
}
vartype #→ OLE variant type. click to toggle source

Returns OLE variant type.

obj = WIN32OLE_VARIANT.new("string")
obj.vartype # => WIN32OLE::VARIANT::VT_BSTR

static VALUE
folevariant_vartype(VALUE self)
{
    struct olevariantdata *pvar;
    Data_Get_Struct(self, struct olevariantdata, pvar);
    return INT2FIX(V_VT(&pvar->var));
}


class WeakRef - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WeakRef

Weak Reference class that allows a referenced object to be garbage-collected.

A WeakRef may be used exactly like the object it references.

Usage:

foo = Object.new            # create a new object instance
p foo.to_s                  # original's class
foo = WeakRef.new(foo)      # reassign foo with WeakRef instance
p foo.to_s                  # should be same class
GC.start                    # start the garbage collector
p foo.to_s                  # should raise exception (recycled)

Example

With help from WeakRef, we can implement our own redimentary WeakHash class.

We will call it WeakHash, since it's really just a Hash except all of it's keys and values can be garbage collected.

require 'weakref'

class WeakHash < Hash
  def []= key, obj
    super WeakRef.new(key), WeakRef.new(obj)
  end
end

This is just a simple implementation, we've opened the Hash class and changed Hash#store to create a new WeakRef object with key and obj parameters before passing them as our key-value pair to the hash.

With this you will have to limit your self to String key's, otherwise you will get an ArgumentError because WeakRef cannot create a finalizer for a Symbol. Symbols are immutable and cannot be garbage collected.

Let's see it in action:

omg = "lol"
c = WeakHash.new
c['foo'] = "bar"
c['baz'] = Object.new
c['qux'] = omg
puts c.inspect
#=> {"foo"=>"bar", "baz"=>#<Object:0x007f4ddfc6cb48>, "qux"=>"lol"}

# Now run the garbage collector
GC.start
c['foo'] #=> nil
c['baz'] #=> nil
c['qux'] #=> nil
omg      #=> "lol"

puts c.inspect
#=> WeakRef::RefError: Invalid Reference - probably recycled

You can see the local variable omg stayed, although it's reference in our hash object was garbage collected, along with the rest of the keys and values. Also, when we tried to inspect our hash, we got a WeakRef::RefError, this is because these objects were also garbage collected.

In Files

  • lib/weakref.rb

Parent

Delegator

Public Class Methods

new(orig) click to toggle source

Creates a weak reference to orig

Raises an ArgumentError if the given orig is immutable, such as Symbol, Fixnum, or Float.

# File lib/weakref.rb, line 82
def initialize(orig)
  case orig
  when true, false, nil
    @delegate_sd_obj = orig
  else
    @@__map[self] = orig
  end
  super
end

Public Instance Methods

weakref_alive?() click to toggle source

Returns true if the referenced object is still alive.

# File lib/weakref.rb, line 103
def weakref_alive?
  !!(@@__map[self] or defined?(@delegate_sd_obj))
end


class WeakRef::RefError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class WeakRef::RefError

RefError is raised when a referenced object has been recycled by the garbage collector

In Files

  • lib/weakref.rb

Parent

StandardError


module Win32 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Win32

Implements bindings to Win32 SSPI functions, focused on authentication to a proxy server over HTTP.

In Files

  • ext/dl/win32/lib/win32/registry.rb
  • ext/dl/win32/lib/win32/resolv.rb
  • ext/dl/win32/lib/win32/sspi.rb
  • ext/fiddle/win32/lib/win32/registry.rb
  • ext/fiddle/win32/lib/win32/resolv.rb


class Win32::Registry - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Win32::Registry

Win32 Registry

win32/registry is registry accessor library for Win32 platform. It uses dl/import to call Win32 Registry APIs.

example

Win32::Registry::HKEY_CURRENT_USER.open('SOFTWARE\foo') do |reg|
  value = reg['foo']                               # read a value
  value = reg['foo', Win32::Registry::REG_SZ]      # read a value with type
  type, value = reg.read('foo')                    # read a value
  reg['foo'] = 'bar'                               # write a value
  reg['foo', Win32::Registry::REG_SZ] = 'bar'      # write a value with type
  reg.write('foo', Win32::Registry::REG_SZ, 'bar') # write a value

  reg.each_value { |name, type, data| ... }        # Enumerate values
  reg.each_key { |key, wtime| ... }                # Enumerate subkeys

  reg.delete_value(name)                         # Delete a value
  reg.delete_key(name)                           # Delete a subkey
  reg.delete_key(name, true)                     # Delete a subkey recursively
end

Reference

Win32::Registry class

Win32 Registry

win32/registry is registry accessor library for Win32 platform. It uses fiddle/import to call Win32 Registry APIs.

example

Win32::Registry::HKEY_CURRENT_USER.open('SOFTWARE\foo') do |reg|
  value = reg['foo']                               # read a value
  value = reg['foo', Win32::Registry::REG_SZ]      # read a value with type
  type, value = reg.read('foo')                    # read a value
  reg['foo'] = 'bar'                               # write a value
  reg['foo', Win32::Registry::REG_SZ] = 'bar'      # write a value with type
  reg.write('foo', Win32::Registry::REG_SZ, 'bar') # write a value

  reg.each_value { |name, type, data| ... }        # Enumerate values
  reg.each_key { |key, wtime| ... }                # Enumerate subkeys

  reg.delete_value(name)                         # Delete a value
  reg.delete_key(name)                           # Delete a subkey
  reg.delete_key(name, true)                     # Delete a subkey recursively
end

Reference

Win32::Registry class

In Files

  • ext/dl/win32/lib/win32/registry.rb
  • ext/fiddle/win32/lib/win32/registry.rb

Parent

Object

Included Modules

  • Win32::Registry::Constants
  • Enumerable

Attributes

disposition[R]

Disposition value (REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY).

hkey[R]

Returns key handle value.

keyname[R]

Same as subkey value of ::open or ::create method.

parent[R]

Win32::Registry object of parent key, or nil if predefeined key.

Public Class Methods

create(hkey, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) { |obj| ... } click to toggle source

— ::create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED)

— ::create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) { |reg| … }

Create or open the registry key subkey under key. You can use predefined key HKEY_* (see Constants)

If subkey is already exists, key is opened and #created? method will return false.

If block is given, the key is closed automatically.

# File ext/dl/win32/lib/win32/registry.rb, line 411
def self.create(hkey, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED)
  newkey, disp = API.CreateKey(hkey.hkey, subkey, opt, desired)
  obj = new(newkey, hkey, subkey, disp)
  if block_given?
    begin
      yield obj
    ensure
      obj.close
    end
  else
    obj
  end
end
expand_environ(str) click to toggle source

Replace %w+% into the environment value of what is contained between the %'s This method is used for REG_EXPAND_SZ.

For detail, see expandEnvironmentStrings Win32 API.

# File ext/dl/win32/lib/win32/registry.rb, line 332
def self.expand_environ(str)
  str.gsub(/%([^%]+)%/) { ENV[$1] || ENV[$1.upcase] || $& }
end
open(hkey, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) { |obj| ... } click to toggle source

— ::open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED)

— ::open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) { |reg| … }

Open the registry key subkey under key. key is Win32::Registry object of parent key. You can use predefined key HKEY_* (see Constants) desired and opt is access mask and key option. For detail, see the MSDN. If block is given, the key is closed automatically.

# File ext/dl/win32/lib/win32/registry.rb, line 383
def self.open(hkey, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED)
  subkey = subkey.chomp('\')
  newkey = API.OpenKey(hkey.hkey, subkey, opt, desired)
  obj = new(newkey, hkey, subkey, REG_OPENED_EXISTING_KEY)
  if block_given?
    begin
      yield obj
    ensure
      obj.close
    end
  else
    obj
  end
end
time2wtime(time) click to toggle source

Convert Time object or Integer object into 64-bit FILETIME.

# File ext/dl/win32/lib/win32/registry.rb, line 363
def self.time2wtime(time)
  time.to_i * 10000000 + 116444736000000000
end
type2name(type) click to toggle source

Convert registry type value to readable string.

# File ext/dl/win32/lib/win32/registry.rb, line 349
def self.type2name(type)
  @@type2name[type] || type.to_s
end
wtime2time(wtime) click to toggle source

Convert 64-bit FILETIME integer into Time object.

# File ext/dl/win32/lib/win32/registry.rb, line 356
def self.wtime2time(wtime)
  Time.at((wtime - 116444736000000000) / 10000000)
end

Public Instance Methods

[](name, *rtype) click to toggle source

Read a registry value named name and return its value data. The class of value is same as read method returns.

If the value type is REG_EXPAND_SZ, returns value data whose environment variables are replaced. If the value type is neither REG_SZ, REG_MULTI_SZ, REG_DWORD, REG_DWORD_BIG_ENDIAN, nor REG_QWORD, TypeError is raised.

The meaning of rtype is same as read method.

# File ext/dl/win32/lib/win32/registry.rb, line 620
def [](name, *rtype)
  type, data = read(name, *rtype)
  case type
  when REG_SZ, REG_DWORD, REG_QWORD, REG_MULTI_SZ
    data
  when REG_EXPAND_SZ
    Registry.expand_environ(data)
  else
    raise TypeError, "Type #{type} is not supported."
  end
end
[]=(name, rtype, value = nil) click to toggle source

Write value to a registry value named name.

If wtype is specified, the value type is it. Otherwise, the value type is depend on class of value: :Integer

REG_DWORD

:String

REG_SZ

:Array

REG_MULTI_SZ
# File ext/dl/win32/lib/win32/registry.rb, line 715
def []=(name, rtype, value = nil)
  if value
    write name, rtype, value
  else
    case value = rtype
    when Integer
      write name, REG_DWORD, value
    when String
      write name, REG_SZ, value
    when Array
      write name, REG_MULTI_SZ, value
    else
      raise TypeError, "Unexpected type #{value.class}"
    end
  end
  value
end
_dump(depth) click to toggle source

marshalling is not allowed

# File ext/dl/win32/lib/win32/registry.rb, line 488
def _dump(depth)
  raise TypeError, "can't dump Win32::Registry"
end
close() click to toggle source

Close key.

After close, most method raise an error.

# File ext/dl/win32/lib/win32/registry.rb, line 511
def close
  API.CloseKey(@hkey)
  @hkey = @parent = @keyname = nil
  @hkeyfinal[0] = nil
end
create(subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED, &blk) click to toggle source

Same as ::create (self, subkey, desired, opt)

# File ext/dl/win32/lib/win32/registry.rb, line 502
def create(subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED, &blk)
  self.class.create(self, subkey, desired, opt, &blk)
end
created?() click to toggle source

Returns if key is created ((newly)). (see ::create) – basically you call create then when you call created? on the instance returned it will tell if it was successful or not

# File ext/dl/win32/lib/win32/registry.rb, line 458
def created?
  @disposition == REG_CREATED_NEW_KEY
end
delete(name) click to toggle source
Alias for: delete_value
delete_key(name, recursive = false) click to toggle source

Delete a subkey named name and all its values.

If recursive is false, the subkey must not have subkeys. Otherwise, this method deletes all subkeys and values recursively.

# File ext/dl/win32/lib/win32/registry.rb, line 778
def delete_key(name, recursive = false)
  if recursive
    open(name, KEY_ALL_ACCESS) do |reg|
      reg.keys.each do |key|
        begin
          reg.delete_key(key, true)
        rescue Error
          #
        end
      end
    end
    API.DeleteKey(@hkey, name)
  else
    begin
      API.EnumKey @hkey, 0
    rescue Error
      return API.DeleteKey(@hkey, name)
    end
    raise Error.new(5) ## ERROR_ACCESS_DENIED
  end
end
delete_value(name) click to toggle source

Delete a registry value named name. We can not delete the `default' value.

# File ext/dl/win32/lib/win32/registry.rb, line 767
def delete_value(name)
  API.DeleteValue(@hkey, name)
end
Also aliased as: delete, delete
each() click to toggle source
Alias for: each_value
each_key() { |subkey, wtime| ... } click to toggle source

Enumerate subkeys.

subkey is String which contains name of subkey. wtime is last write time as FILETIME (64-bit integer). (see ::wtime2time)

# File ext/dl/win32/lib/win32/registry.rb, line 547
def each_key
  index = 0
  while true
    begin
      subkey, wtime = API.EnumKey(@hkey, index)
    rescue Error
      break
    end
    yield subkey, wtime
    index += 1
  end
  index
end
each_value() { |subkey, type, data| ... } click to toggle source

Enumerate values.

# File ext/dl/win32/lib/win32/registry.rb, line 520
def each_value
  index = 0
  while true
    begin
      subkey = API.EnumValue(@hkey, index)
    rescue Error
      break
    end
    begin
      type, data = read(subkey)
    rescue Error
      next
    end
    yield subkey, type, data
    index += 1
  end
  index
end
Also aliased as: each, each
flush() click to toggle source

Write all the attributes into the registry file.

# File ext/dl/win32/lib/win32/registry.rb, line 803
def flush
  API.FlushKey @hkey
end
info() click to toggle source

Returns key information as Array of: :num_keys

The number of subkeys.

:max_key_length

Maximum length of name of subkeys.

:num_values

The number of values.

:max_value_name_length

Maximum length of name of values.

:max_value_length

Maximum length of value of values.

:descriptor_length

Length of security descriptor.

:wtime

Last write time as FILETIME(64-bit integer)

For detail, see RegQueryInfoKey Win32 API.

# File ext/dl/win32/lib/win32/registry.rb, line 826
def info
  API.QueryInfoKey(@hkey)
end
inspect() click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 481
def inspect
  "\#<Win32::Registry key=#{name.inspect}>"
end
keys() click to toggle source

return keys as an array

# File ext/dl/win32/lib/win32/registry.rb, line 564
def keys
  keys_ary = []
  each_key { |key,| keys_ary << key }
  keys_ary
end
name() click to toggle source

Full path of key such as 'HKEY_CURRENT_USERSOFTWAREfoobar'.

# File ext/dl/win32/lib/win32/registry.rb, line 472
def name
  parent = self
  name = @keyname
  while parent = parent.parent
    name = parent.keyname + '\' + name
  end
  name
end
open(subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED, &blk) click to toggle source

Same as ::open (self, subkey, desired, opt)

# File ext/dl/win32/lib/win32/registry.rb, line 495
def open(subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED, &blk)
  self.class.open(self, subkey, desired, opt, &blk)
end
open?() click to toggle source

Returns if key is not closed.

# File ext/dl/win32/lib/win32/registry.rb, line 465
def open?
  !@hkey.nil?
end
read(name, *rtype) click to toggle source

Read a registry value named name and return array of [ type, data ]. When name is nil, the `default' value is read. type is value type. (see Win32::Registry::Constants module) data is value data, its class is: :REG_SZ, REG_EXPAND_SZ

String

:REG_MULTI_SZ

Array of String

:REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD

Integer

:REG_BINARY

String (contains binary data)

When rtype is specified, the value type must be included by rtype array, or TypeError is raised.

# File ext/dl/win32/lib/win32/registry.rb, line 586
def read(name, *rtype)
  type, data = API.QueryValue(@hkey, name)
  unless rtype.empty? or rtype.include?(type)
    raise TypeError, "Type mismatch (expect #{rtype.inspect} but #{type} present)"
  end
  case type
  when REG_SZ, REG_EXPAND_SZ
    [ type, data.chop ]
  when REG_MULTI_SZ
    [ type, data.split(/\0/) ]
  when REG_BINARY
    [ type, data ]
  when REG_DWORD
    [ type, API.unpackdw(data) ]
  when REG_DWORD_BIG_ENDIAN
    [ type, data.unpack('N')[0] ]
  when REG_QWORD
    [ type, API.unpackqw(data) ]
  else
    raise TypeError, "Type #{type} is not supported."
  end
end
read_bin(name) click to toggle source

Read a REG_SZ(#read_s), REG_DWORD(#read_i), or REG_BINARY(#read_bin) registry value named name.

If the values type does not match, TypeError is raised.

# File ext/dl/win32/lib/win32/registry.rb, line 671
def read_bin(name)
  read(name, REG_BINARY)[1]
end
read_i(name) click to toggle source

Read a REG_SZ(#read_s), REG_DWORD(#read_i), or REG_BINARY(#read_bin) registry value named name.

If the values type does not match, TypeError is raised.

# File ext/dl/win32/lib/win32/registry.rb, line 661
def read_i(name)
  read(name, REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD)[1]
end
read_s(name) click to toggle source

Read a REG_SZ(#read_s), REG_DWORD(#read_i), or REG_BINARY(#read_bin) registry value named name.

If the values type does not match, TypeError is raised.

# File ext/dl/win32/lib/win32/registry.rb, line 636
def read_s(name)
  read(name, REG_SZ)[1]
end
read_s_expand(name) click to toggle source

Read a REG_SZ or REG_EXPAND_SZ registry value named name.

If the value type is REG_EXPAND_SZ, environment variables are replaced. Unless the value type is REG_SZ or REG_EXPAND_SZ, TypeError is raised.

# File ext/dl/win32/lib/win32/registry.rb, line 646
def read_s_expand(name)
  type, data = read(name, REG_SZ, REG_EXPAND_SZ)
  if type == REG_EXPAND_SZ
    Registry.expand_environ(data)
  else
    data
  end
end
write(name, type, data) click to toggle source

Write data to a registry value named name. When name is nil, write to the `default' value.

type is type value. (see Registry::Constants module) Class of data must be same as which read method returns.

# File ext/dl/win32/lib/win32/registry.rb, line 683
def write(name, type, data)
  case type
  when REG_SZ, REG_EXPAND_SZ
    data = data.to_s + "\00""
  when REG_MULTI_SZ
    data = data.to_a.join("\00"") + "\00\\00""
  when REG_BINARY
    data = data.to_s
  when REG_DWORD
    data = API.packdw(data.to_i)
  when REG_DWORD_BIG_ENDIAN
    data = [data.to_i].pack('N')
  when REG_QWORD
    data = API.packqw(data.to_i)
  else
    raise TypeError, "Unsupported type #{type}"
  end
  API.SetValue(@hkey, name, type, data, data.length)
end
write_bin(name, value) click to toggle source

Write value to a registry value named name.

The value type is REG_SZ(#write_s), REG_DWORD(#write_i), or REG_BINARY(#write_bin).

# File ext/dl/win32/lib/win32/registry.rb, line 759
def write_bin(name, value)
  write name, REG_BINARY, value.to_s
end
write_i(name, value) click to toggle source

Write value to a registry value named name.

The value type is REG_SZ(#write_s), REG_DWORD(#write_i), or REG_BINARY(#write_bin).

# File ext/dl/win32/lib/win32/registry.rb, line 749
def write_i(name, value)
  write name, REG_DWORD, value.to_i
end
write_s(name, value) click to toggle source

Write value to a registry value named name.

The value type is REG_SZ(#write_s), REG_DWORD(#write_i), or REG_BINARY(#write_bin).

# File ext/dl/win32/lib/win32/registry.rb, line 739
def write_s(name, value)
  write name, REG_SZ, value.to_s
end


module Win32::Registry::API - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Win32::Registry::API

Win32 APIs

Win32 APIs

In Files

  • ext/dl/win32/lib/win32/registry.rb
  • ext/fiddle/win32/lib/win32/registry.rb

Public Instance Methods

CloseKey(hkey) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 306
def CloseKey(hkey)
  check RegCloseKey.call(hkey)
end
CreateKey(hkey, name, opt, desired) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 258
def CreateKey(hkey, name, opt, desired)
  result = packdw(0)
  disp = packdw(0)
  check RegCreateKeyExA.call(hkey, name, 0, 0, opt, desired,
                             0, result, disp)
  [ unpackdw(result), unpackdw(disp) ]
end
DeleteKey(hkey, name) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 298
def DeleteKey(hkey, name)
  check RegDeleteKey.call(hkey, name)
end
DeleteValue(hkey, name) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 294
def DeleteValue(hkey, name)
  check RegDeleteValue.call(hkey, name)
end
EnumKey(hkey, index) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 273
def EnumKey(hkey, index)
  name = ' ' * Constants::MAX_KEY_LENGTH
  size = packdw(Constants::MAX_KEY_LENGTH)
  wtime = ' ' * 8
  check RegEnumKeyExA.call(hkey, index, name, size, 0, 0, 0, wtime)
  [ name[0, unpackdw(size)], unpackqw(wtime) ]
end
EnumValue(hkey, index) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 266
def EnumValue(hkey, index)
  name = ' ' * Constants::MAX_KEY_LENGTH
  size = packdw(Constants::MAX_KEY_LENGTH)
  check RegEnumValueA.call(hkey, index, name, size, 0, 0, 0, 0)
  name[0, unpackdw(size)]
end
FlushKey(hkey) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 302
def FlushKey(hkey)
  check RegFlushKey.call(hkey)
end
OpenKey(hkey, name, opt, desired) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 252
def OpenKey(hkey, name, opt, desired)
  result = packdw(0)
  check RegOpenKeyExA.call(hkey, name, opt, desired, result)
  unpackdw(result)
end
QueryInfoKey(hkey) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 310
def QueryInfoKey(hkey)
  subkeys = packdw(0)
  maxsubkeylen = packdw(0)
  values = packdw(0)
  maxvaluenamelen = packdw(0)
  maxvaluelen = packdw(0)
  secdescs = packdw(0)
  wtime = ' ' * 8
  check RegQueryInfoKey.call(hkey, 0, 0, 0, subkeys, maxsubkeylen, 0,
    values, maxvaluenamelen, maxvaluelen, secdescs, wtime)
  [ unpackdw(subkeys), unpackdw(maxsubkeylen), unpackdw(values),
    unpackdw(maxvaluenamelen), unpackdw(maxvaluelen),
    unpackdw(secdescs), unpackqw(wtime) ]
end
QueryValue(hkey, name) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 281
def QueryValue(hkey, name)
  type = packdw(0)
  size = packdw(0)
  check RegQueryValueExA.call(hkey, name, 0, type, 0, size)
  data = ' ' * unpackdw(size)
  check RegQueryValueExA.call(hkey, name, 0, type, data, size)
  [ unpackdw(type), data[0, unpackdw(size)] ]
end
SetValue(hkey, name, type, data, size) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 290
def SetValue(hkey, name, type, data, size)
  check RegSetValueExA.call(hkey, name, 0, type, data, size)
end
check(result) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 230
def check(result)
  raise Error, result, caller(2) if result != 0
end
packdw(dw) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 234
def packdw(dw)
  [dw].pack('V')
end
packqw(qw) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 243
def packqw(qw)
  [ qw & 0xFFFFFFFF, qw >> 32 ].pack('VV')
end
unpackdw(dw) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 238
def unpackdw(dw)
  dw += [0].pack('V')
  dw.unpack('V')[0]
end
unpackqw(qw) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 247
def unpackqw(qw)
  qw = qw.unpack('VV')
  (qw[1] << 32) | qw[0]
end


module Win32::Registry::Constants - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Win32::Registry::Constants

For detail, see the MSDN.

— HKEY_*

Predefined key ((*handle*)).
These are Integer, not Win32::Registry.

— REG_*

Registry value type.

— KEY_*

Security access mask.

— KEY_OPTIONS_*

Key options.

— REG_CREATED_NEW_KEY

— REG_OPENED_EXISTING_KEY

If the key is created newly or opened existing key.
See also Registry#disposition method.

For detail, see the MSDN.

— HKEY_*

Predefined key ((*handle*)).
These are Integer, not Win32::Registry.

— REG_*

Registry value type.

— KEY_*

Security access mask.

— KEY_OPTIONS_*

Key options.

— REG_CREATED_NEW_KEY

— REG_OPENED_EXISTING_KEY

If the key is created newly or opened existing key.
See also Registry#disposition method.

In Files

  • ext/dl/win32/lib/win32/registry.rb
  • ext/fiddle/win32/lib/win32/registry.rb

Constants

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_DYN_DATA
HKEY_LOCAL_MACHINE
HKEY_PERFORMANCE_DATA
HKEY_PERFORMANCE_NLSTEXT
HKEY_PERFORMANCE_TEXT
HKEY_USERS
KEY_ALL_ACCESS
KEY_CREATE_LINK
KEY_CREATE_SUB_KEY
KEY_ENUMERATE_SUB_KEYS
KEY_EXECUTE
KEY_NOTIFY
KEY_QUERY_VALUE
KEY_READ
KEY_SET_VALUE
KEY_WRITE
MAX_KEY_LENGTH
MAX_VALUE_LENGTH
REG_BINARY
REG_CREATED_NEW_KEY
REG_DWORD
REG_DWORD_BIG_ENDIAN
REG_DWORD_LITTLE_ENDIAN
REG_EXPAND_SZ
REG_FORCE_RESTORE
REG_FULL_RESOURCE_DESCRIPTOR
REG_LEGAL_OPTION
REG_LINK
REG_MULTI_SZ
REG_NONE
REG_NO_LAZY_FLUSH
REG_OPENED_EXISTING_KEY
REG_OPTION_BACKUP_RESTORE
REG_OPTION_CREATE_LINK
REG_OPTION_NON_VOLATILE
REG_OPTION_OPEN_LINK
REG_OPTION_RESERVED
REG_OPTION_VOLATILE
REG_QWORD
REG_QWORD_LITTLE_ENDIAN
REG_REFRESH_HIVE
REG_RESOURCE_LIST
REG_RESOURCE_REQUIREMENTS_LIST
REG_SZ
REG_WHOLE_HIVE_VOLATILE
STANDARD_RIGHTS_READ
STANDARD_RIGHTS_WRITE


class Win32::Registry::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Win32::Registry::Error

Error

Error

In Files

  • ext/dl/win32/lib/win32/registry.rb
  • ext/fiddle/win32/lib/win32/registry.rb

Parent

StandardError

Constants

FormatMessageA

Attributes

code[R]

Public Class Methods

new(code) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 168
def initialize(code)
  @code = code
  msg = "\00"".force_encoding(Encoding::ASCII_8BIT) * 1024
  len = FormatMessageA.call(0x1200, 0, code, 0, msg, 1024, 0)
  msg = msg[0, len].force_encoding(Encoding.find(Encoding.locale_charmap))
  super msg.tr("\r", '').chomp
end


module Win32::Registry::Error::Kernel32 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Win32::Registry::Error::Kernel32

In Files

  • ext/dl/win32/lib/win32/registry.rb
  • ext/fiddle/win32/lib/win32/registry.rb


class Win32::Registry::PredefinedKey - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Win32::Registry::PredefinedKey

Predefined Keys

Predefined Keys

In Files

  • ext/dl/win32/lib/win32/registry.rb
  • ext/fiddle/win32/lib/win32/registry.rb

Parent

Win32::Registry

Public Class Methods

new(hkey, keyname) click to toggle source
# File ext/dl/win32/lib/win32/registry.rb, line 182
def initialize(hkey, keyname)
  @hkey = hkey
  @parent = nil
  @keyname = keyname
  @disposition = REG_OPENED_EXISTING_KEY
end

Public Instance Methods

class() click to toggle source

Fake class method for Win32::Registry#open, Win32::Registry#create

# File ext/dl/win32/lib/win32/registry.rb, line 195
def class
  Registry
end
close() click to toggle source

Predefined keys cannot be closed

# File ext/dl/win32/lib/win32/registry.rb, line 190
def close
  raise Error.new(5) ## ERROR_ACCESS_DENIED
end


module Win32::Resolv - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Win32::Resolv

In Files

  • ext/dl/win32/lib/win32/resolv.rb
  • ext/fiddle/win32/lib/win32/resolv.rb

Constants

API

Public Class Methods

get_hosts_path() click to toggle source
# File ext/dl/win32/lib/win32/resolv.rb, line 13
def self.get_hosts_path
  path = get_hosts_dir
  path = File.expand_path('hosts', path)
  File.exist?(path) ? path : nil
end
get_resolv_info() click to toggle source
# File ext/dl/win32/lib/win32/resolv.rb, line 19
def self.get_resolv_info
  search, nameserver = get_info
  if search.empty?
    search = nil
  else
    search.delete("")
    search.uniq!
  end
  if nameserver.empty?
    nameserver = nil
  else
    nameserver.delete("")
    nameserver.delete("0.0.0.0")
    nameserver.uniq!
  end
  [ search, nameserver ]
end


module Win32::Resolv::Kernel32 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Win32::Resolv::Kernel32

In Files

  • ext/dl/win32/lib/win32/resolv.rb
  • ext/fiddle/win32/lib/win32/resolv.rb


module Win32::SSPI - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Win32::SSPI

In Files

  • ext/dl/win32/lib/win32/sspi.rb

Constants

CredHandle

Some familiar aliases for the SecHandle structure

ISC_REQ_CONFIDENTIALITY
ISC_REQ_CONNECTION
ISC_REQ_PROMPT_FOR_CREDS
ISC_REQ_REPLAY_DETECT

InitializeSecurityContext Requirement flags

ISC_REQ_SEQUENCE_DETECT
ISC_REQ_USE_SESSION_KEY
SECPKG_CRED_BOTH
SECPKG_CRED_INBOUND

Specifies how credential structure requested will be used. Only SECPKG_CRED_OUTBOUND is used here.

SECPKG_CRED_OUTBOUND
SECURITY_NATIVE_DREP

Format of token. NETWORK format is used here.

SECURITY_NETWORK_DREP


module Win32::SSPI::API - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Win32::SSPI::API

Win32 API Functions. Uses Win32API to bind methods to constants contained in class.

In Files

  • ext/dl/win32/lib/win32/sspi.rb

Constants

AcquireCredentialsHandle

Can be called with AcquireCredentialsHandle.call()

DeleteSecurityContext

Can be called with DeleteSecurityContext.call()

FreeCredentialsHandle

Can be called with FreeCredentialsHandle.call()

InitializeSecurityContext

Can be called with InitializeSecurityContext.call()


class Win32::SSPI::Identity - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Win32::SSPI::Identity

SEC_WINNT_AUTH_IDENTITY structure

In Files

  • ext/dl/win32/lib/win32/sspi.rb

Parent

Object

Constants

SEC_WINNT_AUTH_IDENTITY_ANSI

Attributes

domain[RW]
password[RW]
user[RW]

Public Class Methods

new(user = nil, domain = nil, password = nil) click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 138
def initialize(user = nil, domain = nil, password = nil)
        @user = user
        @domain = domain
        @password = password
        @flags = SEC_WINNT_AUTH_IDENTITY_ANSI
end

Public Instance Methods

to_p() click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 145
def to_p
        [@user, @user ? @user.length : 0,
         @domain, @domain ? @domain.length : 0,
         @password, @password ? @password.length : 0,
         @flags].pack("PLPLPLL")
end


class Win32::SSPI::NegotiateAuth - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Win32::SSPI::NegotiateAuth

Handles “Negotiate” type authentication. Geared towards authenticating with a proxy server over HTTP

In Files

  • ext/dl/win32/lib/win32/sspi.rb

Parent

Object

Constants

B64_TOKEN_PREFIX

NTLM tokens start with this header always. Encoding alone adds “==” and newline, so remove those

REQUEST_FLAGS

Default request flags for SSPI functions

Attributes

context[RW]
contextAttributes[RW]
credentials[RW]
domain[RW]
user[RW]

Public Class Methods

new(user = nil, domain = nil) click to toggle source

Creates a new instance ready for authentication as the given user in the given domain. Defaults to current user and domain as defined by ENV and ENV if no arguments are supplied.

# File ext/dl/win32/lib/win32/sspi.rb, line 237
def initialize(user = nil, domain = nil)
        if user.nil? && domain.nil? && ENV["USERNAME"].nil? && ENV["USERDOMAIN"].nil?
                raise "A username or domain must be supplied since they cannot be retrieved from the environment"
        end

        @user = user || ENV["USERNAME"]
        @domain = domain || ENV["USERDOMAIN"]
end
proxy_auth_get(http, path, user = nil, domain = nil) click to toggle source

Given a connection and a request path, performs authentication as the current user and returns the response from a GET request. The connnection should be a Net::HTTP object, and it should have been constructed using the Net::HTTP.Proxy method, but anything that responds to “get” will work. If a user and domain are given, will authenticate as the given user. Returns the response received from the get method (usually Net::HTTPResponse)

# File ext/dl/win32/lib/win32/sspi.rb, line 222
def NegotiateAuth.proxy_auth_get(http, path, user = nil, domain = nil)
        raise "http must respond to :get" unless http.respond_to?(:get)
        nego_auth = self.new user, domain

        resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.get_initial_token }
        if resp["Proxy-Authenticate"]
                resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.complete_authentication(resp["Proxy-Authenticate"].split(" ").last.strip) }
        end

        resp
end

Public Instance Methods

complete_authentication(token) click to toggle source

Takes a token and gets the next token in the Negotiate authentication chain. Token can be Base64 encoded or not. The token can include the “Negotiate” header and it will be stripped. Does not indicate if SEC_I_CONTINUE or SEC_E_OK was returned. Token returned is Base64 encoded w/ all new lines removed.

# File ext/dl/win32/lib/win32/sspi.rb, line 270
              def complete_authentication(token)
                      raise "This object is no longer usable because its resources have been freed." if @cleaned_up

                      # Nil token OK, just set it to empty string
                      token = "" if token.nil?

                      if token.include? "Negotiate"
                              # If the Negotiate prefix is passed in, assume we are seeing "Negotiate <token>" and get the token.
                              token = token.split(" ").last
                      end

                      if token.include? B64_TOKEN_PREFIX
                              # indicates base64 encoded token
token = token.strip.unpack("m")[0]
                      end

                      outputBuffer = SecurityBuffer.new
                      result = SSPIResult.new(API::InitializeSecurityContext.call(@credentials.to_p, @context.to_p, nil,
                              REQUEST_FLAGS, 0, SECURITY_NETWORK_DREP, SecurityBuffer.new(token).to_p, 0,
                              @context.to_p,
                              outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p))

                      if result.ok? then
                              return encode_token(outputBuffer.token)
                      else
                              raise "Error: #{result.to_s}"
                      end
              ensure
                      # need to make sure we don't clean up if we've already cleaned up.
                      clean_up unless @cleaned_up
              end
get_initial_token() click to toggle source

Gets the initial Negotiate token. Returns it as a base64 encoded string suitable for use in HTTP. Can be easily decoded, however.

# File ext/dl/win32/lib/win32/sspi.rb, line 248
def get_initial_token
        raise "This object is no longer usable because its resources have been freed." if @cleaned_up
        get_credentials

        outputBuffer = SecurityBuffer.new
        @context = CtxtHandle.new
        @contextAttributes = "\00"" * 4

        result = SSPIResult.new(API::InitializeSecurityContext.call(@credentials.to_p, nil, nil,
                REQUEST_FLAGS,0, SECURITY_NETWORK_DREP, nil, 0, @context.to_p, outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p))

        if result.ok? then
                return encode_token(outputBuffer.token)
        else
                raise "Error: #{result.to_s}"
        end
end


class Win32::SSPI::SSPIResult - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Win32::SSPI::SSPIResult

Takes a return result from an SSPI function and interprets the value.

In Files

  • ext/dl/win32/lib/win32/sspi.rb

Parent

Object

Constants

SEC_E_INSUFFICIENT_MEMORY

These are generally returned by InitializeSecurityContext

SEC_E_INTERNAL_ERROR
SEC_E_INVALID_HANDLE
SEC_E_INVALID_TOKEN
SEC_E_LOGON_DENIED
SEC_E_NOT_OWNER

These are generally returned by AcquireCredentialsHandle

SEC_E_NO_AUTHENTICATING_AUTHORITY
SEC_E_NO_CREDENTIALS
SEC_E_OK

Good results

SEC_E_SECPKG_NOT_FOUND
SEC_E_TARGET_UNKNOWN
SEC_E_UNKNOWN_CREDENTIALS
SEC_E_UNSUPPORTED_FUNCTION
SEC_E_WRONG_PRINCIPAL
SEC_I_CONTINUE_NEEDED

Attributes

value[R]

Public Class Methods

new(value) click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 181
def initialize(value)
        # convert to unsigned long
        value = [value].pack("L").unpack("L").first
        raise "#{value.to_s(16)} is not a recognized result" unless @@map.has_key? value
        @value = value
end

Public Instance Methods

==(other) click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 196
def ==(other)
        if other.is_a?(SSPIResult)
                @value == other.value
        elsif other.is_a?(Fixnum)
                @value == @@map[other]
        else
                false
        end
end
ok?() click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 192
def ok?
        @value == SEC_I_CONTINUE_NEEDED || @value == SEC_E_OK
end
to_s() click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 188
def to_s
        @@map[@value].to_s
end


class Win32::SSPI::SecurityBuffer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Win32::SSPI::SecurityBuffer

Creates binary representaiton of a SecBufferDesc structure, including the SecBuffer contained inside.

In Files

  • ext/dl/win32/lib/win32/sspi.rb

Parent

Object

Constants

SECBUFFER_TOKEN
SECBUFFER_VERSION
TOKENBUFSIZE

Public Class Methods

new(buffer = nil) click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 84
def initialize(buffer = nil)
        @buffer = buffer || "\00"" * TOKENBUFSIZE
        @bufferSize = @buffer.length
        @type = SECBUFFER_TOKEN
end

Public Instance Methods

bufferSize() click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 90
def bufferSize
        unpack
        @bufferSize
end
bufferType() click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 95
def bufferType
        unpack
        @type
end
to_p() click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 105
def to_p
        # Assumption is that when to_p is called we are going to get a packed structure. Therefore,
        # set @unpacked back to nil so we know to unpack when accessors are next accessed.
        @unpacked = nil
        # Assignment of inner structure to variable is very important here. Without it,
        # will not be able to unpack changes to the structure. Alternative, nested unpacks,
        # does not work (i.e. @struct.unpack("LLP12")[2].unpack("LLP12") results in "no associated pointer")
        @sec_buffer ||= [@bufferSize, @type, @buffer].pack("LLP")
        @struct ||= [SECBUFFER_VERSION, 1, @sec_buffer].pack("LLP")
end
token() click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 100
def token
        unpack
        @buffer
end


class Win32::SSPI::SecurityHandle - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Win32::SSPI::SecurityHandle

SecHandle struct

In Files

  • ext/dl/win32/lib/win32/sspi.rb

Parent

Object

Public Instance Methods

lower() click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 54
def lower
        @struct.unpack("LL")[0]
end
to_p() click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 58
def to_p
        @struct ||= "\00"" * 8
end
upper() click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 50
def upper
        @struct.unpack("LL")[1]
end


class Win32::SSPI::TimeStamp - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Win32::SSPI::TimeStamp

TimeStamp struct

In Files

  • ext/dl/win32/lib/win32/sspi.rb

Parent

Object

Attributes

struct[R]

Public Instance Methods

to_p() click to toggle source
# File ext/dl/win32/lib/win32/sspi.rb, line 70
def to_p
        @struct ||= "\00"" * 8
end


class Win32API - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Win32API

In Files

  • ext/dl/win32/lib/Win32API.rb

Parent

Object

Constants

DLL
POINTER_TYPE
TYPEMAP

Public Class Methods

new(dllname, func, import, export = "0", calltype = :stdcall) click to toggle source
# File ext/dl/win32/lib/Win32API.rb, line 12
def initialize(dllname, func, import, export = "0", calltype = :stdcall)
  @proto = [import].join.tr("VPpNnLlIi", "0SSI").sub(/^(.)0*$/, '\1')
  handle = DLL[dllname] ||= DL.dlopen(dllname)
  @func = DL::CFunc.new(handle[func], TYPEMAP[export.tr("VPpNnLlIi", "0SSI")], func, calltype)
rescue DL::DLError => e
  raise LoadError, e.message, e.backtrace
end

Public Instance Methods

Call(*args) click to toggle source
Alias for: call
call(*args) click to toggle source
# File ext/dl/win32/lib/Win32API.rb, line 20
def call(*args)
  import = @proto.split("")
  args.each_with_index do |x, i|
    args[i], = [x == 0 ? nil : x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
    args[i], = [x].pack("I").unpack("i") if import[i] == "I"
  end
  ret, = @func.call(args)
  return ret || 0
end
Also aliased as: Call


module XML - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XML

In Files

  • lib/rss/xmlparser.rb


class XML::Parser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XML::Parser

In Files

  • lib/rss/xmlparser.rb

Parent

Object

Constants

Error


module XMLEncoding_ja - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XMLEncoding_ja

In Files

  • lib/rss/xmlparser.rb


class XMLEncoding_ja::SJISHandler - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLEncoding_ja::SJISHandler

In Files

  • lib/rss/xmlparser.rb

Parent

Object

Included Modules

  • Kconv


module XMLRPC - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XMLRPC

Author and Copyright

Copyright (C) 2001-2004 by Michael Neumann (mneumann@ntecs.de)

Released under the same term of license as Ruby.

Overview

XMLRPC is a lightweight protocol that enables remote procedure calls over HTTP. It is defined at www.xmlrpc.com.

XMLRPC allows you to create simple distributed computing solutions that span computer languages. Its distinctive feature is its simplicity compared to other approaches like SOAP and CORBA.

The Ruby standard library package 'xmlrpc' enables you to create a server that implements remote procedures and a client that calls them. Very little code is required to achieve either of these.

Example

Try the following code. It calls a standard demonstration remote procedure.

require 'xmlrpc/client'
require 'pp'

server = XMLRPC::Client.new2("http://xmlrpc-c.sourceforge.net/api/sample.php")
result = server.call("sample.sumAndDifference", 5, 3)
pp result

Documentation

See www.ntecs.de/projects/xmlrpc4r. There is plenty of detail there to use the client and implement a server.

Features of XMLRPC for Ruby

  • Extensions

    • Introspection

    • multiCall

    • optionally nil values and integers larger than 32 Bit

  • Server

    • Standalone XML-RPC server

    • CGI-based (works with FastCGI)

    • Apache mod_ruby server

    • WEBrick servlet

  • Client

    • synchronous/asynchronous calls

    • Basic HTTP-401 Authentification

    • HTTPS protocol (SSL)

  • Parsers

    • NQXML (XMLParser::NQXMLStreamParser, XMLParser::NQXMLTreeParser)

    • Expat (XMLParser::XMLStreamParser, XMLParser::XMLTreeParser)

    • REXML (XMLParser::REXMLStreamParser)

    • xml-scan (XMLParser::XMLScanStreamParser)

    • Fastest parser is Expat's XMLParser::XMLStreamParser!

  • General

    • possible to choose between XMLParser module (Expat wrapper) and REXML/NQXML (pure Ruby) parsers

    • Marshalling Ruby objects to Hashs and reconstruct them later from a Hash

    • SandStorm component architecture XMLRPC::Client interface

Howto

Client

require "xmlrpc/client"

# Make an object to represent the XML-RPC server.
server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php")

# Call the remote server and get our result
result = server.call("sample.sumAndDifference", 5, 3)

sum = result["sum"]
difference = result["difference"]

puts "Sum: #{sum}, Difference: #{difference}"

XMLRPC::Client with XML-RPC fault-structure handling

There are two possible ways, of handling a fault-structure:

by catching a XMLRPC::FaultException exception

require "xmlrpc/client"

# Make an object to represent the XML-RPC server.
server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php")

begin
  # Call the remote server and get our result
  result = server.call("sample.sumAndDifference", 5, 3)

  sum = result["sum"]
  difference = result["difference"]

  puts "Sum: #{sum}, Difference: #{difference}"

rescue XMLRPC::FaultException => e
  puts "Error: "
  puts e.faultCode
  puts e.faultString
end

by calling “call2” which returns a boolean

require "xmlrpc/client"

# Make an object to represent the XML-RPC server.
server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php")

# Call the remote server and get our result
ok, result = server.call2("sample.sumAndDifference", 5, 3)

if ok
  sum = result["sum"]
  difference = result["difference"]

  puts "Sum: #{sum}, Difference: #{difference}"
else
  puts "Error: "
  puts result.faultCode
  puts result.faultString
end

Using XMLRPC::Client::Proxy

You can create a Proxy object onto which you can call methods. This way it looks nicer. Both forms, call and call2 are supported through proxy and proxy2. You can additionally give arguments to the Proxy, which will be given to each XML-RPC call using that Proxy.

require "xmlrpc/client"

# Make an object to represent the XML-RPC server.
server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php")

# Create a Proxy object
sample = server.proxy("sample")

# Call the remote server and get our result
result = sample.sumAndDifference(5,3)

sum = result["sum"]
difference = result["difference"]

puts "Sum: #{sum}, Difference: #{difference}"

CGI-based server using XMLRPC::CGIServer

There are also two ways to define handler, the first is like C/PHP, the second like Java, of course both ways can be mixed:

C/PHP-like (handler functions)

require "xmlrpc/server"

s = XMLRPC::CGIServer.new

s.add_handler("sample.sumAndDifference") do |a,b|
  { "sum" => a + b, "difference" => a - b }
end

s.serve

Java-like (handler classes)

require "xmlrpc/server"

s = XMLRPC::CGIServer.new

class MyHandler
  def sumAndDifference(a, b)
    { "sum" => a + b, "difference" => a - b }
  end
end

# NOTE: Security Hole (read below)!!!
s.add_handler("sample", MyHandler.new)
s.serve

To return a fault-structure you have to raise an XMLRPC::FaultException e.g.:

raise XMLRPC::FaultException.new(3, "division by Zero")
Security Note

From Brian Candler:

Above code sample has an extremely nasty security hole, in that you can now call
any method of 'MyHandler' remotely, including methods inherited from Object
and Kernel! For example, in the client code, you can use

  puts server.call("sample.send","`","ls")

(backtick being the method name for running system processes). Needless to
say, 'ls' can be replaced with something else.

The version which binds proc objects (or the version presented below in the next section)
doesn't have this problem, but people may be tempted to use the second version because it's
so nice and 'Rubyesque'. I think it needs a big red disclaimer.

From Michael:

A solution is to undef insecure methods or to use XMLRPC::Service::PublicInstanceMethodsInterface as shown below:

class MyHandler
  def sumAndDifference(a, b)
    { "sum" => a + b, "difference" => a - b }
  end
end

# ... server initialization ...

s.add_handler(XMLRPC::iPIMethods("sample"), MyHandler.new)

# ...

This adds only public instance methods explicitly declared in class MyHandler (and not those inherited from any other class).

With interface declarations

Code sample from the book Ruby Developer's Guide:

require "xmlrpc/server"

class Num
  INTERFACE = XMLRPC::interface("num") {
    meth 'int add(int, int)', 'Add two numbers', 'add'
    meth 'int div(int, int)', 'Divide two numbers'
  }

  def add(a, b) a + b end
  def div(a, b) a / b end
end

s = XMLRPC::CGIServer.new
s.add_handler(Num::INTERFACE, Num.new)
s.serve

Standalone XMLRPC::Server

Same as CGI-based server, the only difference being

server = XMLRPC::CGIServer.new

must be changed to

server = XMLRPC::Server.new(8080)

if you want a server listening on port 8080. The rest is the same.

Choosing a different XMLParser or XMLWriter

The examples above all use the default parser (which is now since 1.8 XMLParser::REXMLStreamParser) and a default XMLRPC::XMLWriter. If you want to use a different XMLParser, then you have to call the XMLRPC::ParserWriterChooseMixin#set_parser method of XMLRPC::Client instances or instances of subclasses of XMLRPC::BasicServer or by editing xmlrpc/config.rb.

XMLRPC::Client Example:

# ...
server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php")
server.set_parser(XMLRPC::XMLParser::XMLParser.new)
# ...

XMLRPC::Server Example:

# ...
s = XMLRPC::CGIServer.new
s.set_parser(XMLRPC::XMLParser::XMLStreamParser.new)
# ...

or:

# ...
server = XMLRPC::Server.new(8080)
server.set_parser(XMLRPC::XMLParser::NQXMLParser.new)
# ...

Note that XMLParser::XMLStreamParser is incredible faster (and uses less memory) than any other parser and scales well for large documents. For example for a 0.5 MB XML document with many tags, XMLParser::XMLStreamParser is ~350 (!) times faster than XMLParser::NQXMLTreeParser and still ~18 times as fast as XMLParser::XMLTreeParser.

You can change the XML-writer by calling method XMLRPC::ParserWriterChooseMixin#set_writer.

In Files

  • lib/xmlrpc/base64.rb
  • lib/xmlrpc/client.rb
  • lib/xmlrpc/config.rb
  • lib/xmlrpc/create.rb
  • lib/xmlrpc/datetime.rb
  • lib/xmlrpc/marshal.rb
  • lib/xmlrpc/parser.rb
  • lib/xmlrpc/server.rb
  • lib/xmlrpc/utils.rb
  • lib/xmlrpc.rb


class XMLRPC::Base64 - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::Base64

This class is necessary for 'xmlrpc4r' to determine that a string should be transmitted base64-encoded and not as a raw-string.

You can use XMLRPC::Base64 on the client and server-side as a parameter and/or return-value.

In Files

  • lib/xmlrpc/base64.rb

Parent

Object

Public Class Methods

decode(str) click to toggle source

Decodes string str with base64 and returns that value.

# File lib/xmlrpc/base64.rb, line 44
def Base64.decode(str)
  str.gsub(/\s+/, "").unpack("m")[0]
end
encode(str) click to toggle source

Encodes string str with base64 and returns that value.

# File lib/xmlrpc/base64.rb, line 49
def Base64.encode(str)
  [str].pack("m")
end
new(str, state = :dec) click to toggle source

Creates a new XMLRPC::Base64 instance with string str as the internal string. When state is :dec it assumes that the string str is not in base64 format (perhaps already decoded), otherwise if state is :enc it decodes str and stores it as the internal string.

# File lib/xmlrpc/base64.rb, line 21
def initialize(str, state = :dec)
  case state
  when :enc
    @str = Base64.decode(str)
  when :dec
    @str = str
  else
    raise ArgumentError, "wrong argument; either :enc or :dec"
  end
end

Public Instance Methods

decoded() click to toggle source

Returns the decoded internal string.

# File lib/xmlrpc/base64.rb, line 33
def decoded
  @str
end
encoded() click to toggle source

Returns the base64 encoded internal string.

# File lib/xmlrpc/base64.rb, line 38
def encoded
  Base64.encode(@str)
end


class XMLRPC::BasicServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::BasicServer

This is the base class for all XML-RPC server-types (CGI, standalone). You can add handler and set a default handler. Do not use this server, as this is/should be an abstract class.

How the method to call is found

The arity (number of accepted arguments) of a handler (method or Proc object) is compared to the given arguments submitted by the client for a RPC, or Remote Procedure Call.

A handler is only called if it accepts the number of arguments, otherwise the search for another handler will go on. When at the end no handler was found, the default_handler, #set_default_handler will be called.

With this technique it is possible to do overloading by number of parameters, but only for Proc handler, because you cannot define two methods of the same name in the same class.

In Files

  • lib/xmlrpc/server.rb

Parent

Object

Included Modules

  • XMLRPC::ParserWriterChooseMixin
  • XMLRPC::ParseContentType

Constants

ERR_MC_EXPECTED_STRUCT
ERR_MC_MISSING_METHNAME
ERR_MC_MISSING_PARAMS
ERR_MC_RECURSIVE_CALL
ERR_MC_WRONG_PARAM
ERR_MC_WRONG_PARAM_PARAMS
ERR_METHOD_MISSING
ERR_UNCAUGHT_EXCEPTION

Public Class Methods

new(class_delim=".") click to toggle source

Creates a new XMLRPC::BasicServer instance, which should not be done, because XMLRPC::BasicServer is an abstract class. This method should be called from a subclass indirectly by a super call in the initialize method.

The paramter class_delim is used by #add_handler, see #add_handler, when an object is added as a handler, to delimit the object-prefix and the method-name.

# File lib/xmlrpc/server.rb, line 56
def initialize(class_delim=".")
  @handler = []
  @default_handler = nil
  @service_hook = nil

  @class_delim = class_delim
  @create = nil
  @parser = nil

  add_multicall     if Config::ENABLE_MULTICALL
  add_introspection if Config::ENABLE_INTROSPECTION
end

Public Instance Methods

add_handler(prefix, obj_or_signature=nil, help=nil, &block) click to toggle source

Adds aBlock to the list of handlers, with name as the name of the method.

Parameters signature and help are used by the Introspection method if specified, where signature is either an Array containing strings each representing a type of it's signature (the first is the return value) or an Array of Arrays if the method has multiple signatures.

Value type-names are “int, boolean, double, string, Time.iso8601, base64, array, struct”.

Parameter help is a String with information about how to call this method etc.

When a method fails, it can tell the client by throwing an XMLRPC::FaultException like in this example:

s.add_handler("michael.div") do |a,b|
  if b == 0
    raise XMLRPC::FaultException.new(1, "division by zero")
  else
    a / b
  end
end

In the case of b==0 the client gets an object back of type XMLRPC::FaultException that has a faultCode and faultString field.

This is the second form of ((<#add_handler|#add_handler>)). To add an object write:

server.add_handler("michael", MyHandlerClass.new)

All public methods of MyHandlerClass are accessible to the XML-RPC clients by michael."name of method". This is where the class_delim in ::new plays it's role, a XML-RPC method-name is defined by prefix + class_delim + "name of method".

The third form of +#add_handler is to use XMLRPC::Service::Interface to generate an object, which represents an interface (with signature and help text) for a handler class.

The interface parameter must be an instance of XMLRPC::Service::Interface. Adds all methods of obj which are defined in the interface to the server.

This is the recommended way of adding services to a server!

# File lib/xmlrpc/server.rb, line 115
def add_handler(prefix, obj_or_signature=nil, help=nil, &block)
  if block_given?
    # proc-handler
    @handler << [prefix, block, obj_or_signature, help]
  else
    if prefix.kind_of? String
      # class-handler
      raise ArgumentError, "Expected non-nil value" if obj_or_signature.nil?
      @handler << [prefix + @class_delim, obj_or_signature]
    elsif prefix.kind_of? XMLRPC::Service::BasicInterface
      # class-handler with interface
      # add all methods
      @handler += prefix.get_methods(obj_or_signature, @class_delim)
    else
      raise ArgumentError, "Wrong type for parameter 'prefix'"
    end
  end
  self
end
add_introspection() click to toggle source

Adds the introspection handlers "system.listMethods", "system.methodSignature" and "system.methodHelp", where only the first one works.

# File lib/xmlrpc/server.rb, line 236
def add_introspection
  add_handler("system.listMethods",%w(array), "List methods available on this XML-RPC server") do
    methods = []
    @handler.each do |name, obj|
      if obj.kind_of? Proc
        methods << name
      else
        obj.class.public_instance_methods(false).each do |meth|
          methods << "#{name}#{meth}"
        end
      end
    end
    methods
  end

  add_handler("system.methodSignature", %w(array string), "Returns method signature") do |meth|
    sigs = []
    @handler.each do |name, obj, sig|
      if obj.kind_of? Proc and sig != nil and name == meth
        if sig[0].kind_of? Array
          # sig contains multiple signatures, e.g. [["array"], ["array", "string"]]
          sig.each {|s| sigs << s}
        else
          # sig is a single signature, e.g. ["array"]
          sigs << sig
        end
      end
    end
    sigs.uniq! || sigs  # remove eventually duplicated signatures
  end

  add_handler("system.methodHelp", %w(string string), "Returns help on using this method") do |meth|
    help = nil
    @handler.each do |name, obj, sig, hlp|
      if obj.kind_of? Proc and name == meth
        help = hlp
        break
      end
    end
    help || ""
  end

  self
end
add_multicall() click to toggle source

Adds the multi-call handler "system.multicall".

# File lib/xmlrpc/server.rb, line 191
def add_multicall
  add_handler("system.multicall", %w(array array), "Multicall Extension") do |arrStructs|
    unless arrStructs.is_a? Array
      raise XMLRPC::FaultException.new(ERR_MC_WRONG_PARAM, "system.multicall expects an array")
    end

    arrStructs.collect {|call|
      if call.is_a? Hash
        methodName = call["methodName"]
        params     = call["params"]

        if params.nil?
          multicall_fault(ERR_MC_MISSING_PARAMS, "Missing params")
        elsif methodName.nil?
          multicall_fault(ERR_MC_MISSING_METHNAME, "Missing methodName")
        else
          if methodName == "system.multicall"
            multicall_fault(ERR_MC_RECURSIVE_CALL, "Recursive system.multicall forbidden")
          else
            unless params.is_a? Array
              multicall_fault(ERR_MC_WRONG_PARAM_PARAMS, "Parameter params have to be an Array")
            else
              ok, val = call_method(methodName, *params)
              if ok
                # correct return value
                [val]
              else
                # exception
                multicall_fault(val.faultCode, val.faultString)
              end
            end
          end
        end

      else
        multicall_fault(ERR_MC_EXPECTED_STRUCT, "system.multicall expected struct")
      end
    }
  end # end add_handler
  self
end
get_default_handler() click to toggle source

Returns the default-handler, which is called when no handler for a method-name is found.

It is either a Proc object or nil.

# File lib/xmlrpc/server.rb, line 170
def get_default_handler
  @default_handler
end
get_service_hook() click to toggle source

Returns the service-hook, which is called on each service request (RPC) unless it's nil.

# File lib/xmlrpc/server.rb, line 137
def get_service_hook
  @service_hook
end
process(data) click to toggle source
# File lib/xmlrpc/server.rb, line 283
def process(data)
  method, params = parser().parseMethodCall(data)
  handle(method, *params)
end
set_default_handler(&handler) click to toggle source

Sets handler as the default-handler, which is called when no handler for a method-name is found.

handler is a code-block.

The default-handler is called with the (XML-RPC) method-name as first argument, and the other arguments are the parameters given by the client-call.

If no block is specified the default of XMLRPC::BasicServer is used, which raises a XMLRPC::FaultException saying “method missing”.

# File lib/xmlrpc/server.rb, line 185
def set_default_handler(&handler)
  @default_handler = handler
  self
end
set_service_hook(&handler) click to toggle source

A service-hook is called for each service request (RPC).

You can use a service-hook for example to wrap existing methods and catch exceptions of them or convert values to values recognized by XMLRPC.

You can disable it by passing nil as the handler parameter.

The service-hook is called with a Proc object along with any parameters.

An example:

server.set_service_hook {|obj, *args|
  begin
    ret = obj.call(*args)  # call the original service-method
    # could convert the return value
  rescue
    # rescue exceptions
  end
}

# File lib/xmlrpc/server.rb, line 161
def set_service_hook(&handler)
  @service_hook = handler
  self
end


class XMLRPC::CGIServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::CGIServer

Implements a CGI-based XML-RPC server.

require "xmlrpc/server"

s = XMLRPC::CGIServer.new

s.add_handler("michael.add") do |a,b|
  a + b
end

s.add_handler("michael.div") do |a,b|
  if b == 0
    raise XMLRPC::FaultException.new(1, "division by zero")
  else
    a / b
  end
end

s.set_default_handler do |name, *args|
  raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
                                   " or wrong number of parameters!")
end

s.serve

Note: Make sure that you don't write to standard-output in a handler, or in any other part of your program, this would cause a CGI-based server to fail!

In Files

  • lib/xmlrpc/server.rb

Parent

XMLRPC::BasicServer

Public Class Methods

new(*a) click to toggle source

Creates a new XMLRPC::CGIServer instance.

All parameters given are by-passed to XMLRPC::BasicServer.new.

You can only create one XMLRPC::CGIServer instance, because more than one makes no sense.

# File lib/xmlrpc/server.rb, line 390
def CGIServer.new(*a)
  @@obj = super(*a) if @@obj.nil?
  @@obj
end
new(*a) click to toggle source
# File lib/xmlrpc/server.rb, line 395
def initialize(*a)
  super(*a)
end

Public Instance Methods

serve() click to toggle source

Call this after you have added all you handlers to the server.

This method processes a XML-RPC method call and sends the answer back to the client.

# File lib/xmlrpc/server.rb, line 403
def serve
  catch(:exit_serve) {
    length = ENV['CONTENT_LENGTH'].to_i

    http_error(405, "Method Not Allowed") unless ENV['REQUEST_METHOD'] == "POST"
    http_error(400, "Bad Request")        unless parse_content_type(ENV['CONTENT_TYPE']).first == "text/xml"
    http_error(411, "Length Required")    unless length > 0

    # TODO: do we need a call to binmode?
    $stdin.binmode if $stdin.respond_to? :binmode
    data = $stdin.read(length)

    http_error(400, "Bad Request")        if data.nil? or data.bytesize != length

    http_write(process(data), "Content-type" => "text/xml; charset=utf-8")
  }
end


class XMLRPC::Client - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::Client

Provides remote procedure calls to a XML-RPC server.

After setting the connection-parameters with ::new which creates a new XMLRPC::Client instance, you can execute a remote procedure by sending the #call or #call2 message to this new instance.

The given parameters indicate which method to call on the remote-side and of course the parameters for the remote procedure.

require "xmlrpc/client"

server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80)
begin
  param = server.call("michael.add", 4, 5)
  puts "4 + 5 = #{param}"
rescue XMLRPC::FaultException => e
  puts "Error:"
  puts e.faultCode
  puts e.faultString
end

or

require "xmlrpc/client"

server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80)
ok, param = server.call2("michael.add", 4, 5)
if ok then
  puts "4 + 5 = #{param}"
else
  puts "Error:"
  puts param.faultCode
  puts param.faultString
end

In Files

  • lib/xmlrpc/client.rb

Parent

Object

Included Modules

  • XMLRPC::ParserWriterChooseMixin
  • XMLRPC::ParseContentType

Constants

USER_AGENT

Attributes

cookie[RW]

Get and set the HTTP Cookie header.

http_header_extra[RW]

Add additional HTTP headers to the request

http_last_response[R]

Returns the Net::HTTPResponse object of the last RPC.

password[R]

Return the corresponding attributes.

timeout[R]

Return the corresponding attributes.

user[R]

Return the corresponding attributes.

Public Class Methods

new(host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil, user=nil, password=nil, use_ssl=nil, timeout=nil) click to toggle source

Creates an object which represents the remote XML-RPC server on the given host. If the server is CGI-based, path is the path to the CGI-script, which will be called, otherwise (in the case of a standalone server) path should be "/RPC2". port is the port on which the XML-RPC server listens.

If proxy_host is given, then a proxy server listening at proxy_host is used. proxy_port is the port of the proxy server.

Default values for host, path and port are 'localhost', '/RPC2' and '80' respectively using SSL '443'.

If user and password are given, each time a request is sent, an Authorization header is sent. Currently only Basic Authentication is implemented, no Digest.

If use_ssl is set to true, communication over SSL is enabled.

Parameter timeout is the time to wait for a XML-RPC response, defaults to 30.

# File lib/xmlrpc/client.rb, line 81
def initialize(host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil,
               user=nil, password=nil, use_ssl=nil, timeout=nil)

  @http_header_extra = nil
  @http_last_response = nil
  @cookie = nil

  @host       = host || "localhost"
  @path       = path || "/RPC2"
  @proxy_host = proxy_host
  @proxy_port = proxy_port
  @proxy_host ||= 'localhost' if @proxy_port != nil
  @proxy_port ||= 8080 if @proxy_host != nil
  @use_ssl    = use_ssl || false
  @timeout    = timeout || 30

  if use_ssl
    require "net/https"
    @port = port || 443
  else
    @port = port || 80
  end

  @user, @password = user, password

  set_auth

  # convert ports to integers
  @port = @port.to_i if @port != nil
  @proxy_port = @proxy_port.to_i if @proxy_port != nil

  # HTTP object for synchronous calls
  @http = net_http(@host, @port, @proxy_host, @proxy_port)
  @http.use_ssl = @use_ssl if @use_ssl
  @http.read_timeout = @timeout
  @http.open_timeout = @timeout

  @parser = nil
  @create = nil
end
new2(uri, proxy=nil, timeout=nil) click to toggle source

Creates an object which represents the remote XML-RPC server at the given uri. The URI should have a host, port, path, user and password. Example: user:password@host:port/path

Raises an ArgumentError if the uri is invalid, or if the protocol isn't http or https.

If a proxy is given it should be in the form of “host:port”.

The optional timeout defaults to 30 seconds.

# File lib/xmlrpc/client.rb, line 135
def new2(uri, proxy=nil, timeout=nil)
  begin
    url = URI(uri)
  rescue URI::InvalidURIError => e
    raise ArgumentError, e.message, e.backtrace
  end

  unless URI::HTTP === url
    raise ArgumentError, "Wrong protocol specified. Only http or https allowed!"
  end

  proto  = url.scheme
  user   = url.user
  passwd = url.password
  host   = url.host
  port   = url.port
  path   = url.path.empty? ? nil : url.request_uri

  proxy_host, proxy_port = (proxy || "").split(":")
  proxy_port = proxy_port.to_i if proxy_port

  self.new(host, path, port, proxy_host, proxy_port, user, passwd, (proto == "https"), timeout)
end
Also aliased as: new_from_uri
new3(hash={}) click to toggle source

Receives a Hash and calls ::new with the corresponding values.

The hash parameter has following case-insensitive keys:

  • host

  • path

  • port

  • proxy_host

  • proxy_port

  • user

  • password

  • use_ssl

  • timeout

# File lib/xmlrpc/client.rb, line 174
def new3(hash={})

  # convert all keys into lowercase strings
  h = {}
  hash.each { |k,v| h[k.to_s.downcase] = v }

  self.new(h['host'], h['path'], h['port'], h['proxy_host'], h['proxy_port'], h['user'], h['password'],
           h['use_ssl'], h['timeout'])
end
Also aliased as: new_from_hash
new_from_hash(hash={}) click to toggle source
Alias for: new3
new_from_uri(uri, proxy=nil, timeout=nil) click to toggle source
Alias for: new2

Public Instance Methods

call(method, *args) click to toggle source

Invokes the method named method with the parameters given by args on the XML-RPC server.

The method parameter is converted into a String and should be a valid XML-RPC method-name.

Each parameter of args must be of one of the following types, where Hash, Struct and Array can contain any of these listed types:

  • Fixnum, Bignum

  • TrueClass, FalseClass, true, false

  • String, Symbol

  • Float

  • Hash, Struct

  • Array

  • Date, Time, XMLRPC::DateTime

  • XMLRPC::Base64

  • A Ruby object which class includes XMLRPC::Marshallable (only if Config::ENABLE_MARSHALLABLE is true). That object is converted into a hash, with one additional key/value pair _class___ which contains the class name for restoring that object later.

The method returns the return-value from the Remote Procedure Call.

The type of the return-value is one of the types shown above.

A Bignum is only allowed when it fits in 32-bit. A XML-RPC dateTime.iso8601 type is always returned as a XMLRPC::DateTime object. Struct is never returned, only a Hash, the same for a Symbol, where as a String is always returned. XMLRPC::Base64 is returned as a String from xmlrpc4r version 1.6.1 on.

If the remote procedure returned a fault-structure, then a XMLRPC::FaultException exception is raised, which has two accessor-methods faultCode an Integer, and faultString a String.

# File lib/xmlrpc/client.rb, line 259
def call(method, *args)
  ok, param = call2(method, *args)
  if ok
    param
  else
    raise param
  end
end
call2(method, *args) click to toggle source

The difference between this method and #call is, that this method will NOT raise a XMLRPC::FaultException exception.

The method returns an array of two values. The first value indicates if the second value is true or an XMLRPC::FaultException.

Both are explained in #call.

Simple to remember: The “2” in “call2” denotes the number of values it returns.

# File lib/xmlrpc/client.rb, line 277
def call2(method, *args)
  request = create().methodCall(method, *args)
  data = do_rpc(request, false)
  parser().parseMethodResponse(data)
end
call2_async(method, *args) click to toggle source

Same as #call2, but can be called concurrently.

See also #call_async

# File lib/xmlrpc/client.rb, line 311
def call2_async(method, *args)
  request = create().methodCall(method, *args)
  data = do_rpc(request, true)
  parser().parseMethodResponse(data)
end
call_async(method, *args) click to toggle source

Similar to #call, however can be called concurrently and use a new connection for each request. In contrast to the corresponding method without the _async suffix, which use connect-alive (one connection for all requests).

Note, that you have to use Thread to call these methods concurrently. The following example calls two methods concurrently:

Thread.new {
  p client.call_async("michael.add", 4, 5)
}

Thread.new {
  p client.call_async("michael.div", 7, 9)
}
# File lib/xmlrpc/client.rb, line 299
def call_async(method, *args)
  ok, param = call2_async(method, *args)
  if ok
    param
  else
    raise param
  end
end
multicall(*methods) click to toggle source

You can use this method to execute several methods on a XMLRPC server which support the multi-call extension.

s.multicall(
  ['michael.add', 3, 4],
  ['michael.sub', 4, 5]
)
# => [7, -1]

# File lib/xmlrpc/client.rb, line 326
def multicall(*methods)
  ok, params = multicall2(*methods)
  if ok
    params
  else
    raise params
  end
end
multicall2(*methods) click to toggle source

Same as #multicall, but returns two parameters instead of raising an XMLRPC::FaultException.

See #call2

# File lib/xmlrpc/client.rb, line 339
def multicall2(*methods)
  gen_multicall(methods, false)
end
multicall2_async(*methods) click to toggle source

Same as #multicall2, but can be called concurrently.

See also #multicall_async

# File lib/xmlrpc/client.rb, line 371
def multicall2_async(*methods)
  gen_multicall(methods, true)
end
multicall_async(*methods) click to toggle source

Similar to #multicall, however can be called concurrently and use a new connection for each request. In contrast to the corresponding method without the _async suffix, which use connect-alive (one connection for all requests).

Note, that you have to use Thread to call these methods concurrently. The following example calls two methods concurrently:

Thread.new {
  p client.multicall_async("michael.add", 4, 5)
}

Thread.new {
  p client.multicall_async("michael.div", 7, 9)
}
# File lib/xmlrpc/client.rb, line 359
def multicall_async(*methods)
  ok, params = multicall2_async(*methods)
  if ok
    params
  else
    raise params
  end
end
password=(new_password) click to toggle source

Changes the password for the Basic Authentication header to new_password

# File lib/xmlrpc/client.rb, line 218
def password=(new_password)
  @password = new_password
  set_auth
end
proxy(prefix=nil, *args) click to toggle source

Returns an object of class XMLRPC::Client::Proxy, initialized with prefix and args.

A proxy object returned by this method behaves like #call, i.e. a call on that object will raise a XMLRPC::FaultException when a fault-structure is returned by that call.

# File lib/xmlrpc/client.rb, line 382
def proxy(prefix=nil, *args)
  Proxy.new(self, prefix, args, :call)
end
proxy2(prefix=nil, *args) click to toggle source

Almost the same like #proxy only that a call on the returned XMLRPC::Client::Proxy object will return two parameters.

See #call2

# File lib/xmlrpc/client.rb, line 390
def proxy2(prefix=nil, *args)
  Proxy.new(self, prefix, args, :call2)
end
proxy2_async(prefix=nil, *args) click to toggle source

Same as #proxy2, but can be called concurrently.

See also #proxy_async

# File lib/xmlrpc/client.rb, line 417
def proxy2_async(prefix=nil, *args)
  Proxy.new(self, prefix, args, :call2_async)
end
proxy_async(prefix=nil, *args) click to toggle source

Similar to #proxy, however can be called concurrently and use a new connection for each request. In contrast to the corresponding method without the _async suffix, which use connect-alive (one connection for all requests).

Note, that you have to use Thread to call these methods concurrently. The following example calls two methods concurrently:

Thread.new {
  p client.proxy_async("michael.add", 4, 5)
}

Thread.new {
  p client.proxy_async("michael.div", 7, 9)
}
# File lib/xmlrpc/client.rb, line 410
def proxy_async(prefix=nil, *args)
  Proxy.new(self, prefix, args, :call_async)
end
timeout=(new_timeout) click to toggle source

Sets the Net::HTTP#read_timeout and Net::HTTP#open_timeout to new_timeout

# File lib/xmlrpc/client.rb, line 204
def timeout=(new_timeout)
  @timeout = new_timeout
  @http.read_timeout = @timeout
  @http.open_timeout = @timeout
end
user=(new_user) click to toggle source

Changes the user for the Basic Authentication header to new_user

# File lib/xmlrpc/client.rb, line 211
def user=(new_user)
  @user = new_user
  set_auth
end


class XMLRPC::Client::Proxy - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::Client::Proxy

XML-RPC calls look nicer!

You can call any method onto objects of that class - the object handles #method_missing and will forward the method call to a XML-RPC server.

Don't use this class directly, instead use the public instance method XMLRPC::Client#proxy or XMLRPC::Client#proxy2.

require "xmlrpc/client"

server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80)

michael  = server.proxy("michael")
michael2 = server.proxy("michael", 4)

# both calls should return the same value '9'.
p michael.add(4,5)
p michael2.add(5)

In Files

  • lib/xmlrpc/client.rb

Parent

Object

Public Class Methods

new(server, prefix, args=[], meth=:call, delim=".") click to toggle source

Creates an object which provides #method_missing.

The given server must be an instance of XMLRPC::Client, which is the XML-RPC server to be used for a XML-RPC call.

prefix and delim will be prepended to the method name called onto this object.

An optional parameter meth is the method to use for a RPC. It can be either, call, call2, call_async, call2_async

args are arguments which are automatically given to every XML-RPC call before being provided through method_missing.

# File lib/xmlrpc/client.rb, line 575
def initialize(server, prefix, args=[], meth=:call, delim=".")
  @server = server
  @prefix = prefix ? prefix + delim : ""
  @args   = args
  @meth   = meth
end

Public Instance Methods

method_missing(mid, *args) click to toggle source

Every method call is forwarded to the XML-RPC server defined in XMLRPC::Client::Proxy#new.

Note: Inherited methods from class Object cannot be used as XML-RPC names, because they get around method_missing.

# File lib/xmlrpc/client.rb, line 587
def method_missing(mid, *args)
  pre = @prefix + mid.to_s
  arg = @args + args
  @server.send(@meth, pre, *arg)
end


module XMLRPC::Config - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XMLRPC::Config

In Files

  • lib/xmlrpc/config.rb

Constants

DEFAULT_PARSER

Available parsers

  • XMLParser::NQXMLTreeParser

  • XMLParser::NQXMLStreamParser

  • XMLParser::XMLTreeParser

  • XMLParser::XMLStreamParser (fastest)

  • XMLParser::REXMLStreamParser

  • XMLParser::XMLScanStreamParser

DEFAULT_WRITER

or XMLWriter::XMLParser

ENABLE_BIGINT

allows integers greater than 32-bit if true

ENABLE_INTROSPECTION

enable Introspection extension by default

ENABLE_MARSHALLING

enable marshalling ruby objects which include XMLRPC::Marshallable

ENABLE_MULTICALL

enable multiCall extension by default

ENABLE_NIL_CREATE

enable <nil/> tag

ENABLE_NIL_PARSER


module XMLRPC::Convert - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XMLRPC::Convert

Helper class used to convert types.

In Files

  • lib/xmlrpc/parser.rb

Public Class Methods

base64(str) click to toggle source

Decodes the given str using XMLRPC::Base64.decode

# File lib/xmlrpc/parser.rb, line 135
def self.base64(str)
  XMLRPC::Base64.decode(str)
end
boolean(str) click to toggle source

Converts a String to true or false

Raises an exception if str is not 0 or 1

# File lib/xmlrpc/parser.rb, line 83
def self.boolean(str)
  case str
  when "0" then false
  when "1" then true
  else
    raise "RPC-value of type boolean is wrong"
  end
end
dateTime(str) click to toggle source

Converts a the given str to a dateTime.iso8601 formatted date.

Raises an exception if the String isn't in dateTime.iso8601 format.

See also, XMLRPC::DateTime

# File lib/xmlrpc/parser.rb, line 104
def self.dateTime(str)
  case str
  when /^(-?\d\d\d\d)-?(\d\d)-?(\d\d)T(\d\d):(\d\d):(\d\d)(?:Z|([+-])(\d\d):?(\d\d))?$/
    a = [$1, $2, $3, $4, $5, $6].collect{|i| i.to_i}
    if $7
      ofs = $8.to_i*3600 + $9.to_i*60
      ofs = -ofs if $7=='+'
      utc = Time.utc(*a) + ofs
      a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ]
    end
    XMLRPC::DateTime.new(*a)
  when /^(-?\d\d)-?(\d\d)-?(\d\d)T(\d\d):(\d\d):(\d\d)(Z|([+-]\d\d):(\d\d))?$/
    a = [$1, $2, $3, $4, $5, $6].collect{|i| i.to_i}
    if a[0] < 70
      a[0] += 2000
    else
      a[0] += 1900
    end
    if $7
      ofs = $8.to_i*3600 + $9.to_i*60
      ofs = -ofs if $7=='+'
      utc = Time.utc(*a) + ofs
      a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ]
    end
    XMLRPC::DateTime.new(*a)
  else
    raise "wrong dateTime.iso8601 format " + str
  end
end
double(str) click to toggle source

Converts a String to a Float

See also String.to_f

# File lib/xmlrpc/parser.rb, line 95
def self.double(str)
  str.to_f
end
fault(hash) click to toggle source

Converts the given hash to an XMLRPC::FaultException object by passing the faultCode and faultString attributes of the Hash to XMLRPC::FaultException.new

Raises an Exception if the given hash doesn't meet the requirements. Those requirements being:

  • 2 keys

  • 'faultCode' key is an Integer

  • 'faultString' key is a String

# File lib/xmlrpc/parser.rb, line 174
def self.fault(hash)
  if hash.kind_of? Hash and hash.size == 2 and
    hash.has_key? "faultCode" and hash.has_key? "faultString" and
    hash["faultCode"].kind_of? Integer and hash["faultString"].kind_of? String

    XMLRPC::FaultException.new(hash["faultCode"], hash["faultString"])
  else
    raise "wrong fault-structure: #{hash.inspect}"
  end
end
int(str) click to toggle source

Converts a String to an Integer

See also String.to_i

# File lib/xmlrpc/parser.rb, line 76
def self.int(str)
  str.to_i
end
struct(hash) click to toggle source

Converts the given hash to a marshalled object.

Returns the given hash if an exception occurs.

# File lib/xmlrpc/parser.rb, line 142
def self.struct(hash)
  # convert to marshalled object
  klass = hash["___class___"]
  if klass.nil? or Config::ENABLE_MARSHALLING == false
    hash
  else
    begin
      mod = Module
      klass.split("::").each {|const| mod = mod.const_get(const.strip)}

      obj = mod.allocate

      hash.delete "___class___"
      hash.each {|key, value|
        obj.instance_variable_set("@#{ key }", value) if key =~ /^([a-zA-Z_]\w*)$/
      }
      obj
    rescue
      hash
    end
  end
end


class XMLRPC::Create - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::Create

Creates XML-RPC call/response documents

In Files

  • lib/xmlrpc/create.rb

Parent

Object

Public Class Methods

new(xml_writer = nil) click to toggle source
# File lib/xmlrpc/create.rb, line 105
def initialize(xml_writer = nil)
  @writer = xml_writer || Config::DEFAULT_WRITER.new
end

Public Instance Methods

methodCall(name, *params) click to toggle source
# File lib/xmlrpc/create.rb, line 110
def methodCall(name, *params)
  name = name.to_s

  if name !~ /[a-zA-Z0-9_.:\/]+/
    raise ArgumentError, "Wrong XML-RPC method-name"
  end

  parameter = params.collect do |param|
    @writer.ele("param", conv2value(param))
  end

  tree = @writer.document(
           @writer.pi("xml", 'version="1.0"'),
           @writer.ele("methodCall",
             @writer.tag("methodName", name),
             @writer.ele("params", *parameter)
           )
         )

  @writer.document_to_str(tree) + "\n"
end
methodResponse(is_ret, *params) click to toggle source

Generates a XML-RPC methodResponse document

When is_ret is false then the params array must contain only one element, which is a structure of a fault return-value.

When is_ret is true then a normal return-value of all the given params is created.

# File lib/xmlrpc/create.rb, line 144
def methodResponse(is_ret, *params)

  if is_ret
    resp = params.collect do |param|
      @writer.ele("param", conv2value(param))
    end

    resp = [@writer.ele("params", *resp)]
  else
    if params.size != 1 or params[0] === XMLRPC::FaultException
      raise ArgumentError, "no valid fault-structure given"
    end
    resp = @writer.ele("fault", conv2value(params[0].to_h))
  end

  tree = @writer.document(
           @writer.pi("xml", 'version="1.0"'),
           @writer.ele("methodResponse", resp)
         )

  @writer.document_to_str(tree) + "\n"
end

Private Instance Methods

conv2value(param) click to toggle source

Converts a Ruby object into a XML-RPC <value> tag

# File lib/xmlrpc/create.rb, line 175
def conv2value(param) # :doc:

    val = case param
    when Fixnum, Bignum
      # XML-RPC's int is 32bit int, and Fixnum also may be beyond 32bit
      if Config::ENABLE_BIGINT
        @writer.tag("i4", param.to_s)
      else
        if param >= -(2**31) and param <= (2**31-1)
          @writer.tag("i4", param.to_s)
        else
          raise "Bignum is too big! Must be signed 32-bit integer!"
        end
      end
    when TrueClass, FalseClass
      @writer.tag("boolean", param ? "1" : "0")

    when Symbol
      @writer.tag("string", param.to_s)

    when String
      @writer.tag("string", param)

    when NilClass
      if Config::ENABLE_NIL_CREATE
        @writer.ele("nil")
      else
        raise "Wrong type NilClass. Not allowed!"
      end

    when Float
      raise "Wrong value #{param}. Not allowed!" unless param.finite?
      @writer.tag("double", param.to_s)

    when Struct
      h = param.members.collect do |key|
        value = param[key]
        @writer.ele("member",
          @writer.tag("name", key.to_s),
          conv2value(value)
        )
      end

      @writer.ele("struct", *h)

    when Hash
      # TODO: can a Hash be empty?

      h = param.collect do |key, value|
        @writer.ele("member",
          @writer.tag("name", key.to_s),
          conv2value(value)
        )
      end

      @writer.ele("struct", *h)

    when Array
      # TODO: can an Array be empty?
      a = param.collect {|v| conv2value(v) }

      @writer.ele("array",
        @writer.ele("data", *a)
      )

    when Time, Date, ::DateTime
      @writer.tag("dateTime.iso8601", param.strftime("%Y%m%dT%H:%M:%S"))

    when XMLRPC::DateTime
      @writer.tag("dateTime.iso8601",
        format("%.4d%02d%02dT%02d:%02d:%02d", *param.to_a))

    when XMLRPC::Base64
      @writer.tag("base64", param.encoded)

    else
      if Config::ENABLE_MARSHALLING and param.class.included_modules.include? XMLRPC::Marshallable
        # convert Ruby object into Hash
        ret = {"___class___" => param.class.name}
        param.instance_variables.each {|v|
          name = v[1..-1]
          val = param.instance_variable_get(v)

          if val.nil?
            ret[name] = val if Config::ENABLE_NIL_CREATE
          else
            ret[name] = val
          end
        }
        return conv2value(ret)
      else
        ok, pa = wrong_type(param)
        if ok
          return conv2value(pa)
        else
          raise "Wrong type!"
        end
      end
    end

    @writer.ele("value", val)
end


class XMLRPC::DateTime - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::DateTime

This class is important to handle XMLRPC dateTime.iso8601 values, correcly, because normal UNIX-dates, ie: Date, only handle dates from year 1970 on, and ruby's native Time class handles dates without the time component.

XMLRPC::DateTime is able to store a XMLRPC dateTime.iso8601 value correctly.

In Files

  • lib/xmlrpc/datetime.rb

Parent

Object

Attributes

day[R]

Return the value of the specified date/time component.

hour[R]

Return the value of the specified date/time component.

min[R]

Return the value of the specified date/time component.

mon[R]

Return the value of the specified date/time component.

month[R]

Return the value of the specified date/time component.

sec[R]

Return the value of the specified date/time component.

year[R]

Return the value of the specified date/time component.

Public Class Methods

new(year, month, day, hour, min, sec) click to toggle source

Creates a new XMLRPC::DateTime instance with the parameters year, month, day as date and hour, min, sec as time.

Raises an ArgumentError if a parameter is out of range, or if year is not of the Integer type.

# File lib/xmlrpc/datetime.rb, line 83
def initialize(year, month, day, hour, min, sec)
  self.year, self.month, self.day = year, month, day
  self.hour, self.min, self.sec   = hour, min, sec
end

Public Instance Methods

==(o) click to toggle source

Returns whether or not all date/time components are an array.

# File lib/xmlrpc/datetime.rb, line 116
def ==(o)
  self.to_a == Array(o) rescue false
end
day=(value) click to toggle source

Set value as the new date/time component.

Raises an ArgumentError if the given value isn't between 1 and 31.

# File lib/xmlrpc/datetime.rb, line 42
def day= (value)
  raise ArgumentError, "date/time out of range" unless (1..31).include? value
  @day = value
end
hour=(value) click to toggle source

Set value as the new date/time component.

Raises an ArgumentError if the given value isn't between 0 and 24.

# File lib/xmlrpc/datetime.rb, line 50
def hour= (value)
  raise ArgumentError, "date/time out of range" unless (0..24).include? value
  @hour = value
end
min=(value) click to toggle source

Set value as the new date/time component.

Raises an ArgumentError if the given value isn't between 0 and 59.

# File lib/xmlrpc/datetime.rb, line 58
def min= (value)
  raise ArgumentError, "date/time out of range" unless (0..59).include? value
  @min = value
end
mon=(value) click to toggle source

Alias for #month=.

Alias for: month=
month=(value) click to toggle source

Set value as the new date/time component.

Raises an ArgumentError if the given value isn't between 1 and 12.

# File lib/xmlrpc/datetime.rb, line 34
def month= (value)
  raise ArgumentError, "date/time out of range" unless (1..12).include? value
  @month = value
end
Also aliased as: mon=
sec=(value) click to toggle source

Set value as the new date/time component.

Raises an ArgumentError if the given value isn't between 0 and 59.

# File lib/xmlrpc/datetime.rb, line 66
def sec= (value)
  raise ArgumentError, "date/time out of range" unless (0..59).include? value
  @sec = value
end
to_a() click to toggle source

Returns all date/time components in an array.

Returns +[year, month, day, hour, min, sec]+.

# File lib/xmlrpc/datetime.rb, line 111
def to_a
  [@year, @month, @day, @hour, @min, @sec]
end
to_date() click to toggle source

Return a Date object of the date which represents self.

The Date object do not contain the time component (only date).

# File lib/xmlrpc/datetime.rb, line 104
def to_date
  Date.new(*to_a[0,3])
end
to_time() click to toggle source

Return a Time object of the date/time which represents self. If the @year is below 1970, this method returns nil, because Time cannot handle years below 1970.

The timezone used is GMT.

# File lib/xmlrpc/datetime.rb, line 93
def to_time
  if @year >= 1970
    Time.gm(*to_a)
  else
    nil
  end
end
year=(value) click to toggle source

Set value as the new date/time component.

Raises ArgumentError if the given value is out of range, or in the case of #year= if value is not of type Integer.

# File lib/xmlrpc/datetime.rb, line 26
def year= (value)
  raise ArgumentError, "date/time out of range" unless value.is_a? Integer
  @year = value
end


class XMLRPC::FaultException - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::FaultException

Raised when the remote procedure returns a fault-structure, which has two accessor-methods faultCode an Integer, and faultString a String.

In Files

  • lib/xmlrpc/parser.rb

Parent

StandardError

Attributes

faultCode[R]
faultString[R]

Public Class Methods

new(faultCode, faultString) click to toggle source

Creates a new XMLRPC::FaultException instance.

faultString is passed to StandardError as the msg of the Exception.

# File lib/xmlrpc/parser.rb, line 58
def initialize(faultCode, faultString)
  @faultCode   = faultCode
  @faultString = faultString
  super(@faultString)
end

Public Instance Methods

to_h() click to toggle source

The faultCode and faultString of the exception in a Hash.

# File lib/xmlrpc/parser.rb, line 65
def to_h
  {"faultCode" => @faultCode, "faultString" => @faultString}
end


class XMLRPC::Marshal - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::Marshal

Marshalling of XMLRPC::Create#methodCall and XMLRPC::Create#methodResponse

In Files

  • lib/xmlrpc/marshal.rb

Parent

Object

Included Modules

  • XMLRPC::ParserWriterChooseMixin

Public Class Methods

dump( param ) click to toggle source
Alias for: dump_response
dump_call( methodName, *params ) click to toggle source
# File lib/xmlrpc/marshal.rb, line 20
def dump_call( methodName, *params )
  new.dump_call( methodName, *params )
end
dump_response( param ) click to toggle source
# File lib/xmlrpc/marshal.rb, line 24
def dump_response( param )
  new.dump_response( param )
end
Also aliased as: dump
load( stringOrReadable ) click to toggle source
Alias for: load_response
load_call( stringOrReadable ) click to toggle source
# File lib/xmlrpc/marshal.rb, line 28
def load_call( stringOrReadable )
  new.load_call( stringOrReadable )
end
load_response( stringOrReadable ) click to toggle source
# File lib/xmlrpc/marshal.rb, line 32
def load_response( stringOrReadable )
  new.load_response( stringOrReadable )
end
Also aliased as: load
new( parser = nil, writer = nil ) click to toggle source
# File lib/xmlrpc/marshal.rb, line 41
def initialize( parser = nil, writer = nil )
  set_parser( parser )
  set_writer( writer )
end

Public Instance Methods

dump_call( methodName, *params ) click to toggle source
# File lib/xmlrpc/marshal.rb, line 46
def dump_call( methodName, *params )
  create.methodCall( methodName, *params )
end
dump_response( param ) click to toggle source
# File lib/xmlrpc/marshal.rb, line 50
def dump_response( param )
  create.methodResponse( ! param.kind_of?( XMLRPC::FaultException ) , param )
end
load_call( stringOrReadable ) click to toggle source

Returns [ methodname, params ]

# File lib/xmlrpc/marshal.rb, line 55
def load_call( stringOrReadable )
  parser.parseMethodCall( stringOrReadable )
end
load_response( stringOrReadable ) click to toggle source

Returns paramOrFault

# File lib/xmlrpc/marshal.rb, line 60
def load_response( stringOrReadable )
  parser.parseMethodResponse( stringOrReadable )[1]
end


module XMLRPC::Marshallable - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XMLRPC::Marshallable

This module enables a user-class to be marshalled by XML-RPC for Ruby into a Hash, with one additional key/value pair _class___ => ClassName

In Files

  • lib/xmlrpc/utils.rb


class XMLRPC::ModRubyServer - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::ModRubyServer

Implements a XML-RPC server, which works with Apache mod_ruby.

Use it in the same way as XMLRPC::CGIServer!

In Files

  • lib/xmlrpc/server.rb

Parent

XMLRPC::BasicServer

Public Class Methods

new(*a) click to toggle source

Creates a new XMLRPC::ModRubyServer instance.

All parameters given are by-passed to XMLRPC::BasicServer.new.

# File lib/xmlrpc/server.rb, line 466
def initialize(*a)
  @ap = Apache::request
  super(*a)
end

Public Instance Methods

serve() click to toggle source

Call this after you have added all you handlers to the server.

This method processes a XML-RPC method call and sends the answer back to the client.

# File lib/xmlrpc/server.rb, line 475
def serve
  catch(:exit_serve) {
    header = {}
    @ap.headers_in.each {|key, value| header[key.capitalize] = value}

    length = header['Content-length'].to_i

    http_error(405, "Method Not Allowed") unless @ap.request_method  == "POST"
    http_error(400, "Bad Request")        unless parse_content_type(header['Content-type']).first == "text/xml"
    http_error(411, "Length Required")    unless length > 0

    # TODO: do we need a call to binmode?
    @ap.binmode
    data = @ap.read(length)

    http_error(400, "Bad Request")        if data.nil? or data.bytesize != length

    http_write(process(data), 200, "Content-type" => "text/xml; charset=utf-8")
  }
end


module XMLRPC::ParseContentType - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XMLRPC::ParseContentType

In Files

  • lib/xmlrpc/utils.rb

Public Instance Methods

parse_content_type(str) click to toggle source
# File lib/xmlrpc/utils.rb, line 164
def parse_content_type(str)
  a, *b = str.split(";")
  return a.strip.downcase, *b
end


module XMLRPC::ParserWriterChooseMixin - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XMLRPC::ParserWriterChooseMixin

Defines ParserWriterChooseMixin, which makes it possible to choose a different XMLWriter and/or XMLParser then the default one.

The Mixin is used in client.rb (class XMLRPC::Client) and server.rb (class XMLRPC::BasicServer)

In Files

  • lib/xmlrpc/utils.rb

Public Instance Methods

set_parser(parser) click to toggle source

Sets the XMLParser to use for parsing XML documents.

Should be an instance of a class from module XMLRPC::XMLParser.

If this method is not called, then XMLRPC::Config::DEFAULT_PARSER is used.

# File lib/xmlrpc/utils.rb, line 39
def set_parser(parser)
  @parser = parser
  self
end
set_writer(writer) click to toggle source

Sets the XMLWriter to use for generating XML output.

Should be an instance of a class from module XMLRPC::XMLWriter.

If this method is not called, then XMLRPC::Config::DEFAULT_WRITER is used.

# File lib/xmlrpc/utils.rb, line 29
def set_writer(writer)
  @create = Create.new(writer)
  self
end


class XMLRPC::Server - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::Server

Implements a standalone XML-RPC server. The method #serve is left if a SIGHUP is sent to the program.

 require "xmlrpc/server"

s = XMLRPC::Server.new(8080)

s.add_handler("michael.add") do |a,b|
  a + b
end

s.add_handler("michael.div") do |a,b|
  if b == 0
    raise XMLRPC::FaultException.new(1, "division by zero")
  else
    a / b
  end
end

s.set_default_handler do |name, *args|
  raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
                                   " or wrong number of parameters!")
end

s.serve

In Files

  • lib/xmlrpc/server.rb

Parent

XMLRPC::WEBrickServlet

Public Class Methods

new(port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a) click to toggle source

Creates a new XMLRPC::Server instance, which is a XML-RPC server listening on the given port and accepts requests for the given host, which is localhost by default.

The server is not started, to start it you have to call #serve.

The optional audit and debug parameters are obsolete!

All additionally provided parameters in *a are by-passed to XMLRPC::BasicServer.new.

# File lib/xmlrpc/server.rb, line 574
def initialize(port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a)
  super(*a)
  require 'webrick'
  @server = WEBrick::HTTPServer.new(:Port => port, :BindAddress => host, :MaxClients => maxConnections,
                                    :Logger => WEBrick::Log.new(stdlog))
  @server.mount("/", self)
end

Public Instance Methods

serve() click to toggle source

Call this after you have added all you handlers to the server. This method starts the server to listen for XML-RPC requests and answer them.

# File lib/xmlrpc/server.rb, line 584
def serve
  signals = %w[INT TERM HUP] & Signal.list.keys
  signals.each { |signal| trap(signal) { @server.shutdown } }

  @server.start
end
shutdown() click to toggle source

Stops and shuts the server down.

# File lib/xmlrpc/server.rb, line 592
def shutdown
  @server.shutdown
end


module XMLRPC::Service - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XMLRPC::Service

In Files

  • lib/xmlrpc/utils.rb


class XMLRPC::Service::BasicInterface - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::Service::BasicInterface

Base class for XMLRPC::Service::Interface definitions, used by XMLRPC::BasicServer#add_handler

In Files

  • lib/xmlrpc/utils.rb

Parent

Object

Attributes

methods[R]
prefix[R]

Public Class Methods

new(prefix) click to toggle source
# File lib/xmlrpc/utils.rb, line 72
def initialize(prefix)
  @prefix = prefix
  @methods = []
end

Public Instance Methods

add_method(sig, help=nil, meth_name=nil) click to toggle source
# File lib/xmlrpc/utils.rb, line 77
def add_method(sig, help=nil, meth_name=nil)
  mname = nil
  sig = [sig] if sig.kind_of? String

  sig = sig.collect do |s|
    name, si = parse_sig(s)
    raise "Wrong signatures!" if mname != nil and name != mname
    mname = name
    si
  end

  @methods << [mname, meth_name || mname, sig, help]
end


class XMLRPC::Service::Interface - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::Service::Interface

Class which wraps a XMLRPC::Service::Interface definition, used by XMLRPC::BasicServer#add_handler

In Files

  • lib/xmlrpc/utils.rb

Parent

XMLRPC::Service::BasicInterface

Public Class Methods

new(prefix, &p) click to toggle source
# File lib/xmlrpc/utils.rb, line 112
def initialize(prefix, &p)
  raise "No interface specified" if p.nil?
  super(prefix)
  instance_eval(&p)
end

Public Instance Methods

get_methods(obj, delim=".") click to toggle source
# File lib/xmlrpc/utils.rb, line 118
def get_methods(obj, delim=".")
  prefix = @prefix + delim
  @methods.collect { |name, meth, sig, help|
    [prefix + name.to_s, obj.method(meth).to_proc, sig, help]
  }
end


class XMLRPC::Service::PublicInstanceMethodsInterface - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::Service::PublicInstanceMethodsInterface

In Files

  • lib/xmlrpc/utils.rb

Parent

XMLRPC::Service::BasicInterface

Public Class Methods

new(prefix) click to toggle source
# File lib/xmlrpc/utils.rb, line 134
def initialize(prefix)
  super(prefix)
end

Public Instance Methods

get_methods(obj, delim=".") click to toggle source
# File lib/xmlrpc/utils.rb, line 138
def get_methods(obj, delim=".")
  prefix = @prefix + delim
  obj.class.public_instance_methods(false).collect { |name|
    [prefix + name.to_s, obj.method(name).to_proc, nil, nil]
  }
end


class XMLRPC::WEBrickServlet - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::WEBrickServlet

Implements a servlet for use with WEBrick, a pure Ruby (HTTP) server framework.

require "webrick"
require "xmlrpc/server"

s = XMLRPC::WEBrickServlet.new
s.add_handler("michael.add") do |a,b|
  a + b
end

s.add_handler("michael.div") do |a,b|
  if b == 0
    raise XMLRPC::FaultException.new(1, "division by zero")
  else
    a / b
  end
end

s.set_default_handler do |name, *args|
  raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
                                   " or wrong number of parameters!")
end

httpserver = WEBrick::HTTPServer.new(:Port => 8080)
httpserver.mount("/RPC2", s)
trap("HUP") { httpserver.shutdown }   # use 1 instead of "HUP" on Windows
httpserver.start

In Files

  • lib/xmlrpc/server.rb

Parent

XMLRPC::BasicServer

Public Class Methods

new(*a) click to toggle source
# File lib/xmlrpc/server.rb, line 628
def initialize(*a)
  super
  require "webrick/httpstatus"
  @valid_ip = nil
end

Public Instance Methods

get_instance(config, *options) click to toggle source
# File lib/xmlrpc/server.rb, line 639
def get_instance(config, *options)
  # TODO: set config & options
  self
end
get_valid_ip() click to toggle source

Return the valid IP addresses that are allowed to connect to the server.

See also, #set_valid_ip

# File lib/xmlrpc/server.rb, line 658
def get_valid_ip
  @valid_ip
end
require_path_info?() click to toggle source

Deprecated from WEBrick/1.2.2, but does not break anything.

# File lib/xmlrpc/server.rb, line 635
def require_path_info?
  false
end
service(request, response) click to toggle source
# File lib/xmlrpc/server.rb, line 662
def service(request, response)

  if @valid_ip
    raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip }
  end

  if request.request_method != "POST"
    raise WEBrick::HTTPStatus::MethodNotAllowed,
          "unsupported method `#{request.request_method}'."
  end

  if parse_content_type(request['Content-type']).first != "text/xml"
    raise WEBrick::HTTPStatus::BadRequest
  end

  length = (request['Content-length'] || 0).to_i

  raise WEBrick::HTTPStatus::LengthRequired unless length > 0

  data = request.body

  if data.nil? or data.bytesize != length
    raise WEBrick::HTTPStatus::BadRequest
  end

  resp = process(data)
  if resp.nil? or resp.bytesize <= 0
    raise WEBrick::HTTPStatus::InternalServerError
  end

  response.status = 200
  response['Content-Length'] = resp.bytesize
  response['Content-Type']   = "text/xml; charset=utf-8"
  response.body = resp
end
set_valid_ip(*ip_addr) click to toggle source

Specifies the valid IP addresses that are allowed to connect to the server.

Each IP is either a String or a Regexp.

# File lib/xmlrpc/server.rb, line 647
def set_valid_ip(*ip_addr)
  if ip_addr.size == 1 and ip_addr[0].nil?
    @valid_ip = nil
  else
    @valid_ip = ip_addr
  end
end


module XMLRPC::XMLParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XMLRPC::XMLParser

Parser for XML-RPC call and response

In Files

  • lib/xmlrpc/parser.rb

Constants

Classes
NQXMLParser
XMLParser

Public Class Methods

each_installed_parser() { |klass| ... } click to toggle source

yields an instance of each installed parser

# File lib/xmlrpc/parser.rb, line 825
def self.each_installed_parser
  XMLRPC::XMLParser::Classes.each do |klass|
    begin
      yield klass.new
    rescue LoadError
    end
  end
end


class XMLRPC::XMLParser::AbstractStreamParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLParser::AbstractStreamParser

In Files

  • lib/xmlrpc/parser.rb

Parent

Object

Public Instance Methods

parseMethodCall(str) click to toggle source
# File lib/xmlrpc/parser.rb, line 499
def parseMethodCall(str)
  parser = @parser_class.new
  parser.parse(str)
  raise "No valid method call - missing method name!" if parser.method_name.nil?
  [parser.method_name, parser.params]
end
parseMethodResponse(str) click to toggle source
# File lib/xmlrpc/parser.rb, line 484
def parseMethodResponse(str)
  parser = @parser_class.new
  parser.parse(str)
  raise "No valid method response!" if parser.method_name != nil
  if parser.fault != nil
    # is a fault structure
    [false, parser.fault]
  else
    # is a normal return value
    raise "Missing return value!" if parser.params.size == 0
    raise "Too many return values. Only one allowed!" if parser.params.size > 1
    [true, parser.params[0]]
  end
end


class XMLRPC::XMLParser::AbstractTreeParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLParser::AbstractTreeParser

In Files

  • lib/xmlrpc/parser.rb

Parent

Object

Public Instance Methods

parseMethodCall(str) click to toggle source
# File lib/xmlrpc/parser.rb, line 196
def parseMethodCall(str)
  methodCall_document(createCleanedTree(str))
end
parseMethodResponse(str) click to toggle source
# File lib/xmlrpc/parser.rb, line 192
def parseMethodResponse(str)
  methodResponse_document(createCleanedTree(str))
end


class XMLRPC::XMLParser::NQXMLTreeParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLParser::NQXMLTreeParser

In Files

  • lib/xmlrpc/parser.rb

Parent

XMLRPC::XMLParser::AbstractTreeParser

Public Class Methods

new() click to toggle source
# File lib/xmlrpc/parser.rb, line 697
def initialize
  require "nqxml/treeparser"
end


class XMLRPC::XMLParser::NQXMLStreamParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLParser::NQXMLStreamParser

In Files

  • lib/xmlrpc/parser.rb

Parent

XMLRPC::XMLParser::AbstractStreamParser

Public Class Methods

new() click to toggle source
# File lib/xmlrpc/parser.rb, line 615
def initialize
  require "nqxml/streamingparser"
  @parser_class = XMLRPCParser
end


class XMLRPC::XMLParser::NQXMLStreamParser::XMLRPCParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLParser::NQXMLStreamParser::XMLRPCParser

In Files

  • lib/xmlrpc/parser.rb

Parent

Object

Included Modules

  • XMLRPC::XMLParser::StreamParserMixin

Public Instance Methods

parse(str) click to toggle source
# File lib/xmlrpc/parser.rb, line 623
def parse(str)
  parser = NQXML::StreamingParser.new(str)
  parser.each do |ele|
    case ele
    when NQXML::Text
      @data = ele.text
      #character(ele.text)
    when NQXML::Tag
      if ele.isTagEnd
        endElement(ele.name)
      else
        startElement(ele.name, ele.attrs)
      end
    end
  end # do
end


class XMLRPC::XMLParser::REXMLStreamParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLParser::REXMLStreamParser

In Files

  • lib/xmlrpc/parser.rb

Parent

XMLRPC::XMLParser::AbstractStreamParser

Public Class Methods

new() click to toggle source
# File lib/xmlrpc/parser.rb, line 724
def initialize
  require "rexml/document"
  @parser_class = StreamListener
end


class XMLRPC::XMLParser::REXMLStreamParser::StreamListener - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLParser::REXMLStreamParser::StreamListener

In Files

  • lib/xmlrpc/parser.rb

Parent

Object

Included Modules

  • XMLRPC::XMLParser::StreamParserMixin

Public Instance Methods

method_missing(*a) click to toggle source
# File lib/xmlrpc/parser.rb, line 737
def method_missing(*a)
  # ignore
end
parse(str) click to toggle source
# File lib/xmlrpc/parser.rb, line 741
def parse(str)
  REXML::Document.parse_stream(str, self)
end


module XMLRPC::XMLParser::StreamParserMixin - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XMLRPC::XMLParser::StreamParserMixin

In Files

  • lib/xmlrpc/parser.rb

Attributes

fault[R]
method_name[R]
params[R]

Public Class Methods

new(*a) click to toggle source
# File lib/xmlrpc/parser.rb, line 512
def initialize(*a)
  super(*a)
  @params = []
  @values = []
  @val_stack = []

  @names = []
  @name = []

  @structs = []
  @struct = {}

  @method_name = nil
  @fault = nil

  @data = nil
end

Public Instance Methods

character(data) click to toggle source
# File lib/xmlrpc/parser.rb, line 595
def character(data)
  if @data
    @data << data
  else
    @data = data
  end
end
endElement(name) click to toggle source
# File lib/xmlrpc/parser.rb, line 550
def endElement(name)
  @data ||= ""
  case name
  when "string"
    @value = @data
  when "i4", "i8", "int"
    @value = Convert.int(@data)
  when "boolean"
    @value = Convert.boolean(@data)
  when "double"
    @value = Convert.double(@data)
  when "dateTime.iso8601"
    @value = Convert.dateTime(@data)
  when "base64"
    @value = Convert.base64(@data)
  when "value"
    @value = @data if @value.nil?
    @values << (@value == :nil ? nil : @value)
  when "array"
    @value = @values
    @values = @val_stack.pop
  when "struct"
    @value = Convert.struct(@struct)

    @name = @names.pop
    @struct = @structs.pop
  when "name"
    @name[0] = @data
  when "member"
    @struct[@name[0]] = @values.pop

  when "param"
    @params << @values[0]
    @values = []

  when "fault"
    @fault = Convert.fault(@values[0])

  when "methodName"
    @method_name = @data
  end

  @data = nil
end
startElement(name, attrs=[]) click to toggle source
# File lib/xmlrpc/parser.rb, line 530
def startElement(name, attrs=[])
  @data = nil
  case name
  when "value"
    @value = nil
  when "nil"
    raise "wrong/unknown XML-RPC type 'nil'" unless Config::ENABLE_NIL_PARSER
    @value = :nil
  when "array"
    @val_stack << @values
    @values = []
  when "struct"
    @names << @name
    @name = []

    @structs << @struct
    @struct = {}
  end
end


class XMLRPC::XMLParser::XMLTreeParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLParser::XMLTreeParser

In Files

  • lib/xmlrpc/parser.rb

Parent

XMLRPC::XMLParser::AbstractTreeParser

Public Class Methods

new() click to toggle source
# File lib/xmlrpc/parser.rb, line 645
def initialize
  require "xmltreebuilder"

  # The new XMLParser library (0.6.2+) uses a slightly different DOM implementation.
  # The following code removes the differences between both versions.
  if defined? XML::DOM::Builder
    return if defined? XML::DOM::Node::DOCUMENT # code below has been already executed
    klass = XML::DOM::Node
    klass.const_set(:DOCUMENT, klass::DOCUMENT_NODE)
    klass.const_set(:TEXT, klass::TEXT_NODE)
    klass.const_set(:COMMENT, klass::COMMENT_NODE)
    klass.const_set(:ELEMENT, klass::ELEMENT_NODE)
  end
end


class XMLRPC::XMLParser::XMLScanStreamParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLParser::XMLScanStreamParser

In Files

  • lib/xmlrpc/parser.rb

Parent

XMLRPC::XMLParser::AbstractStreamParser

Public Class Methods

new() click to toggle source
# File lib/xmlrpc/parser.rb, line 749
def initialize
  require "xmlscan/parser"
  @parser_class = XMLScanParser
end


class XMLRPC::XMLParser::XMLScanStreamParser::XMLScanParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLParser::XMLScanStreamParser::XMLScanParser

In Files

  • lib/xmlrpc/parser.rb

Parent

Object

Included Modules

  • XMLRPC::XMLParser::StreamParserMixin

Constants

Entities

Public Instance Methods

method_missing(*a) click to toggle source
# File lib/xmlrpc/parser.rb, line 805
def method_missing(*a)
end
on_cdata(str) click to toggle source
# File lib/xmlrpc/parser.rb, line 784
def on_cdata(str)
  character(str)
end
on_chardata(str) click to toggle source
# File lib/xmlrpc/parser.rb, line 780
def on_chardata(str)
  character(str)
end
on_charref(code) click to toggle source
# File lib/xmlrpc/parser.rb, line 797
def on_charref(code)
  character(code.chr)
end
on_charref_hex(code) click to toggle source
# File lib/xmlrpc/parser.rb, line 801
def on_charref_hex(code)
  character(code.chr)
end
on_entityref(ent) click to toggle source
# File lib/xmlrpc/parser.rb, line 788
def on_entityref(ent)
  str = Entities[ent]
  if str
    character(str)
  else
    raise "unknown entity"
  end
end
on_stag_end(name) click to toggle source
# File lib/xmlrpc/parser.rb, line 773
def on_stag_end(name); end
on_stag_end_empty(name) click to toggle source
# File lib/xmlrpc/parser.rb, line 775
def on_stag_end_empty(name)
  startElement(name)
  endElement(name)
end
parse(str) click to toggle source
# File lib/xmlrpc/parser.rb, line 765
def parse(str)
  parser  = XMLScan::XMLParser.new(self)
  parser.parse(str)
end


class XMLRPC::XMLParser::XMLStreamParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLParser::XMLStreamParser

In Files

  • lib/xmlrpc/parser.rb

Parent

XMLRPC::XMLParser::AbstractStreamParser

Included Modules

  • XMLRPC::XMLParser::StreamParserMixin

Public Class Methods

new() click to toggle source
# File lib/xmlrpc/parser.rb, line 606
def initialize
  require "xmlparser"
  @parser_class = Class.new(::XMLParser) {
    include StreamParserMixin
  }
end


module XMLRPC::XMLWriter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module XMLRPC::XMLWriter

In Files

  • lib/xmlrpc/create.rb

Constants

Classes

Public Class Methods

each_installed_writer() { |klass| ... } click to toggle source

yields an instance of each installed XML writer

# File lib/xmlrpc/create.rb, line 90
def self.each_installed_writer
  XMLRPC::XMLWriter::Classes.each do |klass|
    begin
      yield klass.new
    rescue LoadError
    end
  end
end


class XMLRPC::XMLWriter::Abstract - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLWriter::Abstract

In Files

  • lib/xmlrpc/create.rb

Parent

Object

Public Instance Methods

ele(name, *children) click to toggle source
# File lib/xmlrpc/create.rb, line 15
def ele(name, *children)
  element(name, nil, *children)
end
tag(name, txt) click to toggle source
# File lib/xmlrpc/create.rb, line 19
def tag(name, txt)
  element(name, nil, text(txt))
end


class XMLRPC::XMLWriter::Simple - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLWriter::Simple

In Files

  • lib/xmlrpc/create.rb

Parent

XMLRPC::XMLWriter::Abstract

Public Instance Methods

document(*params) click to toggle source
# File lib/xmlrpc/create.rb, line 31
def document(*params)
  params.join("")
end
document_to_str(doc) click to toggle source
# File lib/xmlrpc/create.rb, line 27
def document_to_str(doc)
  doc
end
element(name, attrs, *children) click to toggle source
# File lib/xmlrpc/create.rb, line 39
def element(name, attrs, *children)
  raise "attributes not yet implemented" unless attrs.nil?
  if children.empty?
    "<#{name}/>"
  else
    "<#{name}>" + children.join("") + "</#{name}>"
  end
end
pi(name, *params) click to toggle source
# File lib/xmlrpc/create.rb, line 35
def pi(name, *params)
  "<?#{name} " + params.join(" ") + " ?>"
end
text(txt) click to toggle source
# File lib/xmlrpc/create.rb, line 48
def text(txt)
  cleaned = txt.dup
  cleaned.gsub!(/&/, '&amp;')
  cleaned.gsub!(/</, '&lt;')
  cleaned.gsub!(/>/, '&gt;')
  cleaned
end


class XMLRPC::XMLWriter::XMLParser - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMLRPC::XMLWriter::XMLParser

In Files

  • lib/xmlrpc/create.rb

Parent

XMLRPC::XMLWriter::Abstract

Public Class Methods

new() click to toggle source
# File lib/xmlrpc/create.rb, line 61
def initialize
  require "xmltreebuilder"
end

Public Instance Methods

document(*params) click to toggle source
# File lib/xmlrpc/create.rb, line 69
def document(*params)
  XML::SimpleTree::Document.new(*params)
end
document_to_str(doc) click to toggle source
# File lib/xmlrpc/create.rb, line 65
def document_to_str(doc)
  doc.to_s
end
element(name, attrs, *children) click to toggle source
# File lib/xmlrpc/create.rb, line 77
def element(name, attrs, *children)
  XML::SimpleTree::Element.new(name, attrs, *children)
end
pi(name, *params) click to toggle source
# File lib/xmlrpc/create.rb, line 73
def pi(name, *params)
  XML::SimpleTree::ProcessingInstruction.new(name, *params)
end
text(txt) click to toggle source
# File lib/xmlrpc/create.rb, line 81
def text(txt)
  XML::SimpleTree::Text.new(txt)
end


class XMP - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMP

An example printer for irb.

It's much like the standard library PrettyPrint, that shows the value of each expression as it runs.

In order to use this library, you must first require it:

require 'irb/xmp'

Now, you can take advantage of the Object#xmp convenience method.

xmp <<END
  foo = "bar"
  baz = 42
END
#=> foo = "bar"
  #==>"bar"
#=> baz = 42
  #==>42

You can also create an XMP object, with an optional binding to print expressions in the given binding:

ctx = binding
x = XMP.new ctx
x.puts
#=> today = "a good day"
  #==>"a good day"
ctx.eval 'today # is what?'
#=> "a good day"

In Files

  • lib/irb/xmp.rb

Parent

Object

Public Class Methods

new(bind = nil) click to toggle source

Creates a new XMP object.

The top-level binding or, optional bind parameter will be used when creating the workspace. See WorkSpace.new for more information.

This uses the :XMP prompt mode, see Customizing the IRB Prompt at IRB for full detail.

# File lib/irb/xmp.rb, line 55
  def initialize(bind = nil)
    IRB.init_config(nil)
    #IRB.parse_opts
    #IRB.load_modules

    IRB.conf[:PROMPT_MODE] = :XMP

    bind = IRB::Frame.top(1) unless bind
    ws = IRB::WorkSpace.new(bind)
    @io = StringInputMethod.new
    @irb = IRB::Irb.new(ws, @io)
    @irb.context.ignore_sigint = false

#    IRB.conf[:IRB_RC].call(@irb.context) if IRB.conf[:IRB_RC]
    IRB.conf[:MAIN_CONTEXT] = @irb.context
  end

Public Instance Methods

puts(exps) click to toggle source

Evaluates the given exps, for example:

require 'irb/xmp'
x = XMP.new

x.puts '{:a => 1, :b => 2, :c => 3}'
#=> {:a => 1, :b => 2, :c => 3}
  # ==>{:a=>1, :b=>2, :c=>3}
x.puts 'foo = "bar"'
# => foo = "bar"
  # ==>"bar"

# File lib/irb/xmp.rb, line 83
def puts(exps)
  @io.puts exps

  if @irb.context.ignore_sigint
    begin
      trap_proc_b = trap("SIGINT"){@irb.signal_handle}
      catch(:IRB_EXIT) do
        @irb.eval_input
      end
    ensure
      trap("SIGINT", trap_proc_b)
    end
  else
    catch(:IRB_EXIT) do
      @irb.eval_input
    end
  end
end


class XMP::StringInputMethod - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class XMP::StringInputMethod

A custom InputMethod class used by XMP for evaluating string io.

In Files

  • lib/irb/xmp.rb

Parent

IRB::InputMethod

Attributes

encoding[R]

Returns the encoding of last expression printed by puts.

Public Class Methods

new() click to toggle source

Creates a new StringInputMethod object

# File lib/irb/xmp.rb, line 105
def initialize
  super
  @exps = []
end

Public Instance Methods

eof?() click to toggle source

Whether there are any expressions left in this printer.

# File lib/irb/xmp.rb, line 111
def eof?
  @exps.empty?
end
gets() click to toggle source

Reads the next expression from this printer.

See IO#gets for more information.

# File lib/irb/xmp.rb, line 118
def gets
  while l = @exps.shift
    next if /^\s+$/ =~ l
    l.concat "\n"
    print @prompt, l
    break
  end
  l
end
puts(exps) click to toggle source

Concatenates all expressions in this printer, separated by newlines.

An Encoding::CompatibilityError is raised of the given exps's encoding doesn't match the previous expression evaluated.

# File lib/irb/xmp.rb, line 132
def puts(exps)
  if @encoding and exps.encoding != @encoding
    enc = Encoding.compatible?(@exps.join("\n"), exps)
    if enc.nil?
      raise Encoding::CompatibilityError, "Encoding in which the passed expression is encoded is not compatible to the preceding's one"
    else
      @encoding = enc
    end
  else
    @encoding = exps.encoding
  end
  @exps.concat exps.split(/\n/)
end


module YAML - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module YAML

YAML Ain't Markup Language

This module provides a Ruby interface for data serialization in YAML format.

The underlying implementation is the libyaml wrapper Psych.

Usage

Working with YAML can be very simple, for example:

require 'yaml' # STEP ONE, REQUIRE YAML!
# Parse a YAML string
YAML.load("--- foo") #=> "foo"

# Emit some YAML
YAML.dump("foo")     # => "--- foo\n...\n"
{ :a => 'b'}.to_yaml  # => "---\n:a: b\n"

Security

Do not use YAML to load untrusted data. Doing so is unsafe and could allow malicious input to execute arbitrary code inside your application. Please see doc/security.rdoc for more information.

History

Syck was the original for YAML implementation in Ruby's standard library developed by why the lucky stiff.

You can still use Syck, if you prefer, for parsing and emitting YAML, but you must install the 'syck' gem now in order to use it.

In older Ruby versions, ie. <= 1.9, Syck is still provided, however it was completely removed with the release of Ruby 2.0.0.

More info

For more advanced details on the implementation see Psych, and also check out yaml.org for spec details and other helpful information.

In Files

  • lib/rubygems/syck_hack.rb
  • lib/yaml/dbm.rb
  • lib/yaml.rb


class YAML::DBM - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class YAML::DBM

YAML + DBM = YDBM

YAML::DBM provides the same interface as ::DBM.

However, while DBM only allows strings for both keys and values, this library allows one to use most Ruby objects for values by first converting them to YAML. Keys must be strings.

Conversion to and from YAML is performed automatically.

See the documentation for ::DBM and ::YAML for more information.

In Files

  • lib/yaml/dbm.rb

Parent

DBM

Constants

VERSION

Public Instance Methods

[]( key ) click to toggle source

Return value associated with key from database.

Returns nil if there is no such key.

# File lib/yaml/dbm.rb, line 23
def []( key )
    fetch( key )
end
[]=( key, value ) click to toggle source

Set key to value in database.

value will be converted to YAML before storage.

# File lib/yaml/dbm.rb, line 33
def []=( key, val )
    store( key, val )
end
delete( key ) click to toggle source

Deletes value from database associated with key.

Returns value or nil.

# File lib/yaml/dbm.rb, line 82
def delete( key )
    v = super( key )
    if String === v
        v = YAML.load( v )
    end
    v
end
delete_if() { |key, value| ... } click to toggle source

Calls the given block once for each key, value pair in the database. Deletes all entries for which the block returns true.

Returns self.

# File lib/yaml/dbm.rb, line 94
def delete_if # :yields: [key, value]
    del_keys = keys.dup
    del_keys.delete_if { |k| yield( k, fetch( k ) ) == false }
    del_keys.each { |k| delete( k ) }
    self
end
each() click to toggle source
Alias for: each_pair
each_pair() { |key, value| ... } click to toggle source

Calls the given block once for each key, value pair in the database.

Returns self.

# File lib/yaml/dbm.rb, line 111
def each_pair # :yields: [key, value]
    keys.each { |k| yield k, fetch( k ) }
    self
end
Also aliased as: each
each_value() { |value| ... } click to toggle source

Calls the given block for each value in database.

Returns self.

# File lib/yaml/dbm.rb, line 119
def each_value # :yields: value
    super { |v| yield YAML.load( v ) }
    self
end
fetch( key, ifnone = nil ) click to toggle source
fetch( key, &block )

Return value associated with key.

If there is no value for key and no block is given, returns ifnone.

Otherwise, calls block passing in the given key.

# File lib/yaml/dbm.rb, line 46
def fetch( keystr, ifnone = nil )
    begin
        val = super( keystr )
        return YAML.load( val ) if String === val
    rescue IndexError
    end
    if block_given?
        yield keystr
    else
        ifnone
    end
end
has_value?( val ) click to toggle source

Returns true if specified value is found in the database.

# File lib/yaml/dbm.rb, line 130
def has_value?( val )
    each_value { |v| return true if v == val }
    return false
end
index( keystr ) click to toggle source

Deprecated, used #key instead.

Note: #index makes warning from internal of ::DBM#index. It says '#index is deprecated; use #key', but #key behaves not same as #index.

# File lib/yaml/dbm.rb, line 66
def index( keystr )
    super( keystr.to_yaml )
end
invert() click to toggle source

Returns a Hash (not a DBM database) created by using each value in the database as a key, with the corresponding key as its value.

Note that all values in the hash will be Strings, but the keys will be actual objects.

# File lib/yaml/dbm.rb, line 140
def invert
    h = {}
    keys.each { |k| h[ self.fetch( k ) ] = k }
    h
end
key( keystr ) click to toggle source
# File lib/yaml/dbm.rb, line 70
def key( keystr )
    invert[keystr]
end
reject() { |k, v| ... } click to toggle source

Converts the contents of the database to an in-memory Hash, then calls Hash#reject with the specified code block, returning a new Hash.

# File lib/yaml/dbm.rb, line 103
def reject
    hsh = self.to_hash
    hsh.reject { |k,v| yield k, v }
end
replace( hsh ) click to toggle source

Replaces the contents of the database with the contents of the specified object. Takes any object which implements the #each_pair method, including Hash and DBM objects.

# File lib/yaml/dbm.rb, line 149
def replace( hsh )
    clear
    update( hsh )
end
select( &block ) click to toggle source
select( *keys )

If a block is provided, returns a new array containing [key, value] pairs for which the block returns true.

Otherwise, same as values_at

# File lib/yaml/dbm.rb, line 172
def select( *keys )
    if block_given?
        self.keys.collect { |k| v = self[k]; [k, v] if yield k, v }.compact
    else
        values_at( *keys )
    end
end
shift() click to toggle source

Removes a [key, value] pair from the database, and returns it. If the database is empty, returns nil.

The order in which values are removed/returned is not guaranteed.

# File lib/yaml/dbm.rb, line 158
def shift
    a = super
    a[1] = YAML.load( a[1] ) if a
    a
end
store( key, value ) click to toggle source

Stores value in database with key as the index. value is converted to YAML before being stored.

Returns value

# File lib/yaml/dbm.rb, line 187
def store( key, val )
    super( key, val.to_yaml )
    val
end
to_a() click to toggle source

Converts the contents of the database to an array of [key, value] arrays, and returns it.

# File lib/yaml/dbm.rb, line 206
def to_a
    a = []
    keys.each { |k| a.push [ k, self.fetch( k ) ] }
    a
end
to_hash() click to toggle source

Converts the contents of the database to an in-memory Hash object, and returns it.

# File lib/yaml/dbm.rb, line 215
def to_hash
    h = {}
    keys.each { |k| h[ k ] = self.fetch( k ) }
    h
end
update( hsh ) click to toggle source

Updates the database with multiple values from the specified object. Takes any object which implements the #each_pair method, including Hash and DBM objects.

Returns self.

# File lib/yaml/dbm.rb, line 197
def update( hsh )
    hsh.each_pair do |k,v|
        self.store( k, v )
    end
    self
end
values() click to toggle source

Returns an array of values from the database.

# File lib/yaml/dbm.rb, line 125
def values
    super.collect { |v| YAML.load( v ) }
end
values_at( *keys ) click to toggle source

Returns an array containing the values associated with the given keys.

# File lib/yaml/dbm.rb, line 75
def values_at( *keys )
    keys.collect { |k| fetch( k ) }
end


class YAML::Store - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class YAML::Store

YAML::Store provides the same functionality as PStore, except it uses YAML to dump objects instead of Marshal.

Example

require 'yaml/store'

Person = Struct.new :first_name, :last_name

people = [Person.new("Bob", "Smith"), Person.new("Mary", "Johnson")]

store = YAML::Store.new "test.store"

store.transaction do
  store["people"] = people
  store["greeting"] = { "hello" => "world" }
end

After running the above code, the contents of “test.store” will be:

---
people:
- !ruby/struct:Person
  first_name: Bob
  last_name: Smith
- !ruby/struct:Person
  first_name: Mary
  last_name: Johnson
greeting:
  hello: world

In Files

  • lib/yaml/store.rb

Parent

PStore

Public Class Methods

initialize( file_name, yaml_opts = {} ) click to toggle source

Creates a new YAML::Store object, which will store data in file_name. If the file does not already exist, it will be created.

Options passed in through yaml_opts will be used when converting the store to YAML via Object#to_yaml.

# File lib/yaml/store.rb, line 49
def initialize file_name, yaml_opts = {}
  @opt = yaml_opts
  super
end


module YAML::Syck - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module YAML::Syck

In Files

  • lib/rubygems/syck_hack.rb


class YAML::Syck::DefaultKey - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class YAML::Syck::DefaultKey

In Files

  • lib/rubygems/syck_hack.rb

Parent

Object


module Zlib - Ruby 2.0.0-p576 Standard Library API Reference API Reference

module Zlib

This module provides access to the zlib library. Zlib is designed to be a portable, free, general-purpose, legally unencumbered – that is, not covered by any patents – lossless data-compression library for use on virtually any computer hardware and operating system.

The zlib compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data.

The zlib compressed data format is described in RFC 1950, which is a wrapper around a deflate stream which is described in RFC 1951.

The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of IO. The gzip format is described in RFC 1952 which is also a wrapper around a deflate stream.

The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single-file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib.

See your system's zlib.h for further information about zlib

Sample usage

Using the wrapper to compress strings with default parameters is quite simple:

require "zlib"

data_to_compress = File.read("don_quixote.txt")

puts "Input size: #{data_to_compress.size}"
#=> Input size: 2347740

data_compressed = Zlib::Deflate.deflate(data_to_compress)

puts "Compressed size: #{data_compressed.size}"
#=> Compressed size: 887238

uncompressed_data = Zlib::Inflate.inflate(data_compressed)

puts "Uncompressed data is: #{uncompressed_data}"
#=> Uncompressed data is: The Project Gutenberg EBook of Don Quixote...

Class tree

  • Zlib::Deflate

  • Zlib::Inflate

  • Zlib::ZStream

  • Zlib::Error

    • Zlib::StreamEnd

    • Zlib::NeedDict

    • Zlib::DataError

    • Zlib::StreamError

    • Zlib::MemError

    • Zlib::BufError

    • Zlib::VersionError

(if you have GZIP_SUPPORT)

  • Zlib::GzipReader

  • Zlib::GzipWriter

  • Zlib::GzipFile

  • Zlib::GzipFile::Error

    • Zlib::GzipFile::LengthError

    • Zlib::GzipFile::CRCError

    • Zlib::GzipFile::NoFooter

In Files

  • ext/zlib/zlib.c

Constants

ASCII

Zlib::ZStream#data_type.

BEST_COMPRESSION

Slowest compression level, but with the best space savings.

BEST_SPEED

Fastest compression level, but with with lowest space savings.

BINARY

Zlib::ZStream#data_type.

DEFAULT_COMPRESSION

Default compression level which is a good trade-off between space and time

DEFAULT_STRATEGY

Default deflate strategy which is used for normal data.

DEF_MEM_LEVEL

The default memory level for allocating zlib deflate compression state.

FILTERED

Deflate strategy for data produced by a filter (or predictor). The effect of FILTERED is to force more Huffman codes and less string matching; it is somewhat intermediate between DEFAULT_STRATEGY and HUFFMAN_ONLY. Filtered data consists mostly of small values with a somewhat random distribution.

FINISH

Processes all pending input and flushes pending output.

FIXED

Deflate strategy which prevents the use of dynamic Huffman codes, allowing for a simpler decoder for specialized applications.

FULL_FLUSH

Flushes all output as with SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Like SYNC_FLUSH, using FULL_FLUSH too often can seriously degrade compression.

HUFFMAN_ONLY

Deflate strategy which uses Huffman codes only (no string matching).

MAX_MEM_LEVEL

The maximum memory level for allocating zlib deflate compression state.

MAX_WBITS

Zlib::Inflate.new for details.

NO_COMPRESSION

No compression, passes through data untouched. Use this for appending pre-compressed data to a deflate stream.

NO_FLUSH

NO_FLUSH is the default flush method and allows deflate to decide how much data to accumulate before producing output in order to maximize compression.

OS_AMIGA

OS code for Amiga hosts

OS_ATARI

OS code for Atari hosts

OS_CODE

The OS code of current host

OS_CPM

OS code for CP/M hosts

OS_MACOS

OS code for Mac OS hosts

OS_MSDOS

OS code for MSDOS hosts

OS_OS2

OS code for OS2 hosts

OS_QDOS

OS code for QDOS hosts

OS_RISCOS

OS code for RISC OS hosts

OS_TOPS20

OS code for TOPS-20 hosts

OS_UNIX

OS code for UNIX hosts

OS_UNKNOWN

OS code for unknown hosts

OS_VMCMS

OS code for VM OS hosts

OS_VMS

OS code for VMS hosts

OS_WIN32

OS code for Win32 hosts

OS_ZSYSTEM

OS code for Z-System hosts

RLE

Deflate compression strategy designed to be almost as fast as HUFFMAN_ONLY, but give better compression for PNG image data.

SYNC_FLUSH

The SYNC_FLUSH method flushes all pending output to the output buffer and the output is aligned on a byte boundary. Flushing may degrade compression so it should be used only when necessary, such as at a request or response boundary for a network stream.

TEXT

Zlib::ZStream#data_type.

UNKNOWN

Zlib::ZStream#data_type.

VERSION

The Ruby/zlib version string.

ZLIB_VERSION

The string which represents the version of zlib.h

Public Class Methods

adler32(string, adler) click to toggle source

Calculates Adler-32 checksum for string, and returns updated value of adler. If string is omitted, it returns the Adler-32 initial value. If adler is omitted, it assumes that the initial value is given to adler.

FIXME: expression.

static VALUE
rb_zlib_adler32(int argc, VALUE *argv, VALUE klass)
{
    return do_checksum(argc, argv, adler32);
}
adler32_combine(adler1, adler2, len2) click to toggle source

Combine two Adler-32 check values in to one. alder1 is the first Adler-32 value, adler2 is the second Adler-32 value. len2 is the length of the string used to generate adler2.

static VALUE
rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
{
  return ULONG2NUM(
        adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
}
crc32(string, adler) click to toggle source

Calculates CRC checksum for string, and returns updated value of crc. If string is omitted, it returns the CRC initial value. If crc is omitted, it assumes that the initial value is given to crc.

FIXME: expression.

static VALUE
rb_zlib_crc32(int argc, VALUE *argv, VALUE klass)
{
    return do_checksum(argc, argv, crc32);
}
crc32_combine(crc1, crc2, len2) click to toggle source

Combine two CRC-32 check values in to one. crc1 is the first CRC-32 value, crc2 is the second CRC-32 value. len2 is the length of the string used to generate crc2.

static VALUE
rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2)
{
  return ULONG2NUM(
        crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
}
crc_table() click to toggle source

Returns the table for calculating CRC checksum as an array.

static VALUE
rb_zlib_crc_table(VALUE obj)
{
#if !defined(HAVE_TYPE_Z_CRC_T)
    /* z_crc_t is defined since zlib-1.2.7. */
    typedef unsigned long z_crc_t;
#endif
    const z_crc_t *crctbl;
    VALUE dst;
    int i;

    crctbl = get_crc_table();
    dst = rb_ary_new2(256);

    for (i = 0; i < 256; i++) {
        rb_ary_push(dst, rb_uint2inum(crctbl[i]));
    }
    return dst;
}
deflate(string[, level]) click to toggle source
Zlib::Deflate.deflate(string[, level])

Compresses the given string. Valid values of level are Zlib::NO_COMPRESSION, Zlib::BEST_SPEED, Zlib::BEST_COMPRESSION, Zlib::DEFAULT_COMPRESSION, or an integer from 0 to 9 (the default is 6).

This method is almost equivalent to the following code:

def deflate(string, level)
  z = Zlib::Deflate.new(level)
  dst = z.deflate(string, Zlib::FINISH)
  z.close
  dst
end

See also ::inflate

static VALUE
rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass)
{
    struct zstream z;
    VALUE src, level, dst, args[2];
    int err, lev;

    rb_scan_args(argc, argv, "11", &src, &level);

    lev = ARG_LEVEL(level);
    StringValue(src);
    zstream_init_deflate(&z);
    err = deflateInit(&z.stream, lev);
    if (err != Z_OK) {
        raise_zlib_error(err, z.stream.msg);
    }
    ZSTREAM_READY(&z);

    args[0] = (VALUE)&z;
    args[1] = src;
    dst = rb_ensure(deflate_run, (VALUE)args, zstream_end, (VALUE)&z);

    OBJ_INFECT(dst, src);
    return dst;
}
inflate(string) click to toggle source
Zlib::Inflate.inflate(string)

Decompresses string. Raises a Zlib::NeedDict exception if a preset dictionary is needed for decompression.

This method is almost equivalent to the following code:

def inflate(string)
  zstream = Zlib::Inflate.new
  buf = zstream.inflate(string)
  zstream.finish
  zstream.close
  buf
end

See also ::deflate

static VALUE
rb_inflate_s_inflate(VALUE obj, VALUE src)
{
    struct zstream z;
    VALUE dst, args[2];
    int err;

    StringValue(src);
    zstream_init_inflate(&z);
    err = inflateInit(&z.stream);
    if (err != Z_OK) {
        raise_zlib_error(err, z.stream.msg);
    }
    ZSTREAM_READY(&z);

    args[0] = (VALUE)&z;
    args[1] = src;
    dst = rb_ensure(inflate_run, (VALUE)args, zstream_end, (VALUE)&z);

    OBJ_INFECT(dst, src);
    return dst;
}
zlib_version() click to toggle source

Returns the string which represents the version of zlib library.

static VALUE
rb_zlib_version(VALUE klass)
{
    VALUE str;

    str = rb_str_new2(zlibVersion());
    OBJ_TAINT(str);  /* for safe */
    return str;
}


class Zlib::BufError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::BufError

Subclass of Zlib::Error when zlib returns a Z_BUF_ERROR.

Usually if no progress is possible.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::Error


class Zlib::DataError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::DataError

Subclass of Zlib::Error when zlib returns a Z_DATA_ERROR.

Usually if a stream was prematurely freed.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::Error


class Zlib::Deflate - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::Deflate

Zlib::Deflate is the class for compressing data. See Zlib::ZStream for more information.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::ZStream

Public Class Methods

deflate(string[, level]) click to toggle source
Zlib::Deflate.deflate(string[, level])

Compresses the given string. Valid values of level are Zlib::NO_COMPRESSION, Zlib::BEST_SPEED, Zlib::BEST_COMPRESSION, Zlib::DEFAULT_COMPRESSION, or an integer from 0 to 9 (the default is 6).

This method is almost equivalent to the following code:

def deflate(string, level)
  z = Zlib::Deflate.new(level)
  dst = z.deflate(string, Zlib::FINISH)
  z.close
  dst
end

See also Zlib.inflate

static VALUE
rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass)
{
    struct zstream z;
    VALUE src, level, dst, args[2];
    int err, lev;

    rb_scan_args(argc, argv, "11", &src, &level);

    lev = ARG_LEVEL(level);
    StringValue(src);
    zstream_init_deflate(&z);
    err = deflateInit(&z.stream, lev);
    if (err != Z_OK) {
        raise_zlib_error(err, z.stream.msg);
    }
    ZSTREAM_READY(&z);

    args[0] = (VALUE)&z;
    args[1] = src;
    dst = rb_ensure(deflate_run, (VALUE)args, zstream_end, (VALUE)&z);

    OBJ_INFECT(dst, src);
    return dst;
}
Zlib::Deflate.new(level=DEFAULT_COMPRESSION, window_bits=MAX_WBITS, mem_level=DEF_MEM_LEVEL, strategy=DEFAULT_STRATEGY) click to toggle source

Creates a new deflate stream for compression. If a given argument is nil, the default value of that argument is used.

The level sets the compression level for the deflate stream between 0 (no compression) and 9 (best compression. The following constants have been defined to make code more readable:

  • Zlib::NO_COMPRESSION = 0

  • Zlib::BEST_SPEED = 1

  • Zlib::DEFAULT_COMPRESSION = 6

  • Zlib::BEST_COMPRESSION = 9

The window_bits sets the size of the history buffer and should be between 8 and 15. Larger values of this parameter result in better compression at the expense of memory usage.

The mem_level specifies how much memory should be allocated for the internal compression state. 1 uses minimum memory but is slow and reduces compression ratio while 9 uses maximum memory for optimal speed. The default value is 8. Two constants are defined:

  • Zlib::DEF_MEM_LEVEL

  • Zlib::MAX_MEM_LEVEL

The strategy sets the deflate compression strategy. The following strategies are available:

Zlib::DEFAULT_STRATEGY

For normal data

Zlib::FILTERED

For data produced by a filter or predictor

Zlib::FIXED

Prevents dynamic Huffman codes

Zlib::HUFFMAN_ONLY

Prevents string matching

Zlib::RLE

Designed for better compression of PNG image data

See the constants for further description.

Examples

Basic

open "compressed.file", "w+" do |io|
  io << Zlib::Deflate.new.deflate(File.read("big.file"))
end

Custom compression

open "compressed.file", "w+" do |compressed_io|
  deflate = Zlib::Deflate.new(Zlib::BEST_COMPRESSION,
                              Zlib::MAX_WBITS,
                              Zlib::MAX_MEM_LEVEL,
                              Zlib::HUFFMAN_ONLY)

  begin
    open "big.file" do |big_io|
      until big_io.eof? do
        compressed_io << zd.deflate(big_io.read(16384))
      end
    end
  ensure
    deflate.close
  end
end

While this example will work, for best optimization review the flags for your specific time, memory usage and output space requirements.

static VALUE
rb_deflate_initialize(int argc, VALUE *argv, VALUE obj)
{
    struct zstream *z;
    VALUE level, wbits, memlevel, strategy;
    int err;

    rb_scan_args(argc, argv, "04", &level, &wbits, &memlevel, &strategy);
    Data_Get_Struct(obj, struct zstream, z);

    err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED,
                       ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),
                       ARG_STRATEGY(strategy));
    if (err != Z_OK) {
        raise_zlib_error(err, z->stream.msg);
    }
    ZSTREAM_READY(z);

    return obj;
}

Public Instance Methods

<< string click to toggle source

Inputs string into the deflate stream just like #deflate, but returns the Zlib::Deflate object itself. The output from the stream is preserved in output buffer.

static VALUE
rb_deflate_addstr(VALUE obj, VALUE src)
{
    OBJ_INFECT(obj, src);
    do_deflate(get_zstream(obj), src, Z_NO_FLUSH);
    return obj;
}
deflate(string, flush = Zlib::NO_FLUSH) → String click to toggle source
deflate(string, flush = Zlib::NO_FLUSH) { |chunk| ... } → nil

Inputs string into the deflate stream and returns the output from the stream. On calling this method, both the input and the output buffers of the stream are flushed. If string is nil, this method finishes the stream, just like Zlib::ZStream#finish.

If a block is given consecutive deflated chunks from the string are yielded to the block and nil is returned.

The flush parameter specifies the flush mode. The following constants may be used:

Zlib::NO_FLUSH

The default

Zlib::SYNC_FLUSH

Flushes the output to a byte boundary

Zlib::FULL_FLUSH

SYNC_FLUSH + resets the compression state

Zlib::FINISH

Pending input is processed, pending output is flushed.

See the constants for further description.

static VALUE
rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
{
    struct zstream *z = get_zstream(obj);
    VALUE src, flush;

    rb_scan_args(argc, argv, "11", &src, &flush);
    OBJ_INFECT(obj, src);
    do_deflate(z, src, ARG_FLUSH(flush));

    return zstream_detach_buffer(z);
}
flush(flush = Zlib::SYNC_FLUSH) → String click to toggle source
flush(flush = Zlib::SYNC_FLUSH) { |chunk| ... } → nil

This method is equivalent to deflate('', flush). This method is just provided to improve the readability of your Ruby program. If a block is given chunks of deflate output are yielded to the block until the buffer is flushed.

See #deflate for detail on the flush constants NO_FLUSH, SYNC_FLUSH, FULL_FLUSH and FINISH.

static VALUE
rb_deflate_flush(int argc, VALUE *argv, VALUE obj)
{
    struct zstream *z = get_zstream(obj);
    VALUE v_flush;
    int flush;

    rb_scan_args(argc, argv, "01", &v_flush);
    flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
    if (flush != Z_NO_FLUSH) {  /* prevent Z_BUF_ERROR */
        zstream_run(z, (Bytef*)"", 0, flush);
    }

    return zstream_detach_buffer(z);
}
initialize_copy(p1) click to toggle source

Duplicates the deflate stream.

static VALUE
rb_deflate_init_copy(VALUE self, VALUE orig)
{
    struct zstream *z1, *z2;
    int err;

    Data_Get_Struct(self, struct zstream, z1);
    z2 = get_zstream(orig);

    if (z1 == z2) return self;
    err = deflateCopy(&z1->stream, &z2->stream);
    if (err != Z_OK) {
        raise_zlib_error(err, 0);
    }
    z1->input = NIL_P(z2->input) ? Qnil : rb_str_dup(z2->input);
    z1->buf   = NIL_P(z2->buf)   ? Qnil : rb_str_dup(z2->buf);
    z1->buf_filled = z2->buf_filled;
    z1->flags = z2->flags;

    return self;
}
params(level, strategy) click to toggle source

Changes the parameters of the deflate stream to allow changes between different types of data that require different types of compression. Any unprocessed data is flushed before changing the params.

See ::new for a description of level and strategy.

static VALUE
rb_deflate_params(VALUE obj, VALUE v_level, VALUE v_strategy)
{
    struct zstream *z = get_zstream(obj);
    int level, strategy;
    int err;
    uInt n;

    level = ARG_LEVEL(v_level);
    strategy = ARG_STRATEGY(v_strategy);

    n = z->stream.avail_out;
    err = deflateParams(&z->stream, level, strategy);
    z->buf_filled += n - z->stream.avail_out;
    while (err == Z_BUF_ERROR) {
        rb_warning("deflateParams() returned Z_BUF_ERROR");
        zstream_expand_buffer(z);
        n = z->stream.avail_out;
        err = deflateParams(&z->stream, level, strategy);
        z->buf_filled += n - z->stream.avail_out;
    }
    if (err != Z_OK) {
        raise_zlib_error(err, z->stream.msg);
    }

    return Qnil;
}
set_dictionary(string) click to toggle source

Sets the preset dictionary and returns string. This method is available just only after ::new or Zlib::ZStream#reset method was called. See zlib.h for details.

Can raise errors of Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the expected one (incorrect adler32 value)

static VALUE
rb_deflate_set_dictionary(VALUE obj, VALUE dic)
{
    struct zstream *z = get_zstream(obj);
    VALUE src = dic;
    int err;

    OBJ_INFECT(obj, dic);
    StringValue(src);
    err = deflateSetDictionary(&z->stream,
                               (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
    if (err != Z_OK) {
        raise_zlib_error(err, z->stream.msg);
    }

    return dic;
}


class Zlib::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::Error

The superclass for all exceptions raised by Ruby/zlib.

The following exceptions are defined as subclasses of Zlib::Error. These exceptions are raised when zlib library functions return with an error status.

  • Zlib::StreamEnd

  • Zlib::NeedDict

  • Zlib::DataError

  • Zlib::StreamError

  • Zlib::MemError

  • Zlib::BufError

  • Zlib::VersionError

In Files

  • ext/zlib/zlib.c

Parent

StandardError


class Zlib::GzipFile - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::GzipFile

Zlib::GzipFile is an abstract class for handling a gzip formatted compressed file. The operations are defined in the subclasses, Zlib::GzipReader for reading, and Zlib::GzipWriter for writing.

GzipReader should be used by associating an IO, or IO-like, object.

Method Catalogue

  • ::wrap

  • ::open (Zlib::GzipReader.open and Zlib::GzipWriter.open)

  • close

  • closed?

  • comment

  • comment= (Zlib::GzipWriter#comment=)

  • crc

  • eof? (Zlib::GzipReader#eof?)

  • finish

  • level

  • lineno (Zlib::GzipReader#lineno)

  • lineno= (Zlib::GzipReader#lineno=)

  • mtime

  • mtime= (Zlib::GzipWriter#mtime=)

  • orig_name

  • #orig_name (Zlib::GzipWriter#orig_name=)

  • os_code

  • path (when the underlying IO supports path)

  • sync

  • sync=

  • to_io

(due to internal structure, documentation may appear under Zlib::GzipReader or Zlib::GzipWriter)

In Files

  • ext/zlib/zlib.c

Parent

Object

Public Class Methods

Zlib::GzipReader.wrap(io, ...) { |gz| ... } click to toggle source
Zlib::GzipWriter.wrap(io, ...) { |gz| ... }

Creates a GzipReader or GzipWriter associated with io, passing in any necessary extra options, and executes the block with the newly created object just like File.open.

The GzipFile object will be closed automatically after executing the block. If you want to keep the associated IO object open, you may call #finish method in the block.

static VALUE
rb_gzfile_s_wrap(int argc, VALUE *argv, VALUE klass)
{
    return gzfile_wrap(argc, argv, klass, 0);
}

Public Instance Methods

close() click to toggle source

Closes the GzipFile object. This method calls close method of the associated IO object. Returns the associated IO object.

static VALUE
rb_gzfile_close(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE io;

    io = gz->io;
    gzfile_close(gz, 1);
    return io;
}
closed?() click to toggle source

Same as IO#closed?

static VALUE
rb_gzfile_closed_p(VALUE obj)
{
    struct gzfile *gz;
    Data_Get_Struct(obj, struct gzfile, gz);
    return NIL_P(gz->io) ? Qtrue : Qfalse;
}
comment() click to toggle source

Returns comments recorded in the gzip file header, or nil if the comments is not present.

static VALUE
rb_gzfile_comment(VALUE obj)
{
    VALUE str = get_gzfile(obj)->comment;
    if (!NIL_P(str)) {
        str = rb_str_dup(str);
    }
    OBJ_TAINT(str);  /* for safe */
    return str;
}
crc() click to toggle source

Returns CRC value of the uncompressed data.

static VALUE
rb_gzfile_crc(VALUE obj)
{
    return rb_uint2inum(get_gzfile(obj)->crc);
}
finish() click to toggle source

Closes the GzipFile object. Unlike #close, this method never calls the close method of the associated IO object. Returns the associated IO object.

static VALUE
rb_gzfile_finish(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE io;

    io = gz->io;
    gzfile_close(gz, 0);
    return io;
}
level() click to toggle source

Returns compression level.

static VALUE
rb_gzfile_level(VALUE obj)
{
    return INT2FIX(get_gzfile(obj)->level);
}
mtime() click to toggle source

Returns last modification time recorded in the gzip file header.

static VALUE
rb_gzfile_mtime(VALUE obj)
{
    return rb_time_new(get_gzfile(obj)->mtime, (time_t)0);
}
orig_name() click to toggle source

Returns original filename recorded in the gzip file header, or nil if original filename is not present.

static VALUE
rb_gzfile_orig_name(VALUE obj)
{
    VALUE str = get_gzfile(obj)->orig_name;
    if (!NIL_P(str)) {
        str = rb_str_dup(str);
    }
    OBJ_TAINT(str);  /* for safe */
    return str;
}
os_code() click to toggle source

Returns OS code number recorded in the gzip file header.

static VALUE
rb_gzfile_os_code(VALUE obj)
{
    return INT2FIX(get_gzfile(obj)->os_code);
}
sync() click to toggle source

Same as IO#sync

static VALUE
rb_gzfile_sync(VALUE obj)
{
    return (get_gzfile(obj)->z.flags & GZFILE_FLAG_SYNC) ? Qtrue : Qfalse;
}
sync = flag click to toggle source

Same as IO. If flag is true, the associated IO object must respond to the flush method. While sync mode is true, the compression ratio decreases sharply.

static VALUE
rb_gzfile_set_sync(VALUE obj, VALUE mode)
{
    struct gzfile *gz = get_gzfile(obj);

    if (RTEST(mode)) {
        gz->z.flags |= GZFILE_FLAG_SYNC;
    }
    else {
        gz->z.flags &= ~GZFILE_FLAG_SYNC;
    }
    return mode;
}
to_io() click to toggle source

Same as IO.

static VALUE
rb_gzfile_to_io(VALUE obj)
{
    return get_gzfile(obj)->io;
}


class Zlib::GzipFile::CRCError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::GzipFile::CRCError

Raised when the CRC checksum recorded in gzip file footer is not equivalent to the CRC checksum of the actual uncompressed data.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::GzipFile::Error


class Zlib::GzipFile::Error - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::GzipFile::Error

Base class of errors that occur when processing GZIP files.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::Error

Attributes

input[R]

input gzipped string

Public Instance Methods

inspect() click to toggle source

Constructs a String of the GzipFile Error

static VALUE
gzfile_error_inspect(VALUE error)
{
    VALUE str = rb_call_super(0, 0);
    VALUE input = rb_attr_get(error, id_input);

    if (!NIL_P(input)) {
        rb_str_resize(str, RSTRING_LEN(str)-1);
        rb_str_cat2(str, ", input=");
        rb_str_append(str, rb_str_inspect(input));
        rb_str_cat2(str, ">");
    }
    return str;
}


class Zlib::GzipFile::LengthError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::GzipFile::LengthError

Raised when the data length recorded in the gzip file footer is not equivalent to the length of the actual uncompressed data.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::GzipFile::Error


class Zlib::GzipFile::NoFooter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::GzipFile::NoFooter

Raised when gzip file footer is not found.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::GzipFile::Error


class Zlib::GzipReader - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::GzipReader

Zlib::GzipReader is the class for reading a gzipped file. GzipReader should be used an IO, or -IO-like, object.

Zlib::GzipReader.open('hoge.gz') {|gz|
  print gz.read
}

File.open('hoge.gz') do |f|
  gz = Zlib::GzipReader.new(f)
  print gz.read
  gz.close
end

Method Catalogue

The following methods in Zlib::GzipReader are just like their counterparts in IO, but they raise Zlib::Error or Zlib::GzipFile::Error exception if an error was found in the gzip file.

  • each

  • each_line

  • each_byte

  • gets

  • getc

  • lineno

  • lineno=

  • read

  • readchar

  • readline

  • readlines

  • ungetc

Be careful of the footer of the gzip file. A gzip file has the checksum of pre-compressed data in its footer. GzipReader checks all uncompressed data against that checksum at the following cases, and if it fails, raises Zlib::GzipFile::NoFooter, Zlib::GzipFile::CRCError, or Zlib::GzipFile::LengthError exception.

  • When an reading request is received beyond the end of file (the end of compressed data). That is, when #read, #gets, or some other methods for reading returns nil.

  • When Zlib::GzipFile#close method is called after the object reaches the end of file.

  • When #unused method is called after the object reaches the end of file.

The rest of the methods are adequately described in their own documentation.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::GzipFile

Included Modules

  • Enumerable

Public Class Methods

Zlib::GzipReader.new(io, options = {}) click to toggle source

Creates a GzipReader object associated with io. The GzipReader object reads gzipped data from io, and parses/decompresses it. The io must have a read method that behaves same as the IO#read.

The options hash may be used to set the encoding of the data. :external_encoding, :internal_encoding and :encoding may be set as in IO::new.

If the gzip file header is incorrect, raises an Zlib::GzipFile::Error exception.

static VALUE
rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
{
    VALUE io, opt = Qnil;
    struct gzfile *gz;
    int err;

    Data_Get_Struct(obj, struct gzfile, gz);
    rb_scan_args(argc, argv, "1:", &io, &opt);

    /* this is undocumented feature of zlib */
    err = inflateInit2(&gz->z.stream, -MAX_WBITS);
    if (err != Z_OK) {
        raise_zlib_error(err, gz->z.stream.msg);
    }
    gz->io = io;
    ZSTREAM_READY(&gz->z);
    gzfile_read_header(gz);
    rb_gzfile_ecopts(gz, opt);

    if (rb_respond_to(io, id_path)) {
        gz->path = rb_funcall(gz->io, id_path, 0);
        rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
    }

    return obj;
}
Zlib::GzipReader.open(filename) {|gz| ... } click to toggle source

Opens a file specified by filename as a gzipped file, and returns a GzipReader object associated with that file. Further details of this method are in ::new and ZLib::GzipFile.wrap.

static VALUE
rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass)
{
    return gzfile_s_open(argc, argv, klass, "rb");
}

Public Instance Methods

bytes() click to toggle source

This is a deprecated alias for each_byte.

static VALUE
rb_gzreader_bytes(VALUE obj)
{
    rb_warn("Zlib::GzipReader#bytes is deprecated; use #each_byte instead");
    if (!rb_block_given_p())
        return rb_enumeratorize(obj, ID2SYM(rb_intern("each_byte")), 0, 0);
    return rb_gzreader_each_byte(obj);
}
each(*args) click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
{
    VALUE str;

    RETURN_ENUMERATOR(obj, 0, 0);

    while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
        rb_yield(str);
    }
    return obj;
}
each_byte() click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_each_byte(VALUE obj)
{
    VALUE c;

    RETURN_ENUMERATOR(obj, 0, 0);

    while (!NIL_P(c = rb_gzreader_getbyte(obj))) {
        rb_yield(c);
    }
    return Qnil;
}
each_char() click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_each_char(VALUE obj)
{
    VALUE c;

    RETURN_ENUMERATOR(obj, 0, 0);

    while (!NIL_P(c = rb_gzreader_getc(obj))) {
        rb_yield(c);
    }
    return Qnil;
}
each_line(*args) click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
{
    VALUE str;

    RETURN_ENUMERATOR(obj, 0, 0);

    while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
        rb_yield(str);
    }
    return obj;
}
eof() click to toggle source

Returns true or false whether the stream has reached the end.

static VALUE
rb_gzfile_eof_p(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
}
eof?() click to toggle source

Returns true or false whether the stream has reached the end.

static VALUE
rb_gzfile_eof_p(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
}
getbyte() click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_getbyte(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE dst;

    dst = gzfile_read(gz, 1);
    if (!NIL_P(dst)) {
        dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff);
    }
    return dst;
}
getc() click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_getc(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);

    return gzfile_getc(gz);
}
gets(*args) click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_gets(int argc, VALUE *argv, VALUE obj)
{
    VALUE dst;
    dst = gzreader_gets(argc, argv, obj);
    if (!NIL_P(dst)) {
        rb_lastline_set(dst);
    }
    return dst;
}
lineno() click to toggle source

The line number of the last row read from this file.

static VALUE
rb_gzfile_lineno(VALUE obj)
{
    return INT2NUM(get_gzfile(obj)->lineno);
}
lineno=(p1) click to toggle source

Specify line number of the last row read from this file.

static VALUE
rb_gzfile_set_lineno(VALUE obj, VALUE lineno)
{
    struct gzfile *gz = get_gzfile(obj);
    gz->lineno = NUM2INT(lineno);
    return lineno;
}
lines(*args) click to toggle source

This is a deprecated alias for each_line.

static VALUE
rb_gzreader_lines(int argc, VALUE *argv, VALUE obj)
{
    rb_warn("Zlib::GzipReader#lines is deprecated; use #each_line instead");
    if (!rb_block_given_p())
        return rb_enumeratorize(obj, ID2SYM(rb_intern("each_line")), argc, argv);
    return rb_gzreader_each(argc, argv, obj);
}
pos() click to toggle source

Total number of output bytes output so far.

static VALUE
rb_gzfile_total_out(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    return rb_uint2inum(gz->z.stream.total_out - gz->z.buf_filled);
}
read(p1 = v1) click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_read(int argc, VALUE *argv, VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE vlen;
    long len;

    rb_scan_args(argc, argv, "01", &vlen);
    if (NIL_P(vlen)) {
        return gzfile_read_all(gz);
    }

    len = NUM2INT(vlen);
    if (len < 0) {
        rb_raise(rb_eArgError, "negative length %ld given", len);
    }
    return gzfile_read(gz, len);
}
readbyte() click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_readbyte(VALUE obj)
{
    VALUE dst;
    dst = rb_gzreader_getbyte(obj);
    if (NIL_P(dst)) {
        rb_raise(rb_eEOFError, "end of file reached");
    }
    return dst;
}
readchar() click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_readchar(VALUE obj)
{
    VALUE dst;
    dst = rb_gzreader_getc(obj);
    if (NIL_P(dst)) {
        rb_raise(rb_eEOFError, "end of file reached");
    }
    return dst;
}
readline(*args) click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_readline(int argc, VALUE *argv, VALUE obj)
{
    VALUE dst;
    dst = rb_gzreader_gets(argc, argv, obj);
    if (NIL_P(dst)) {
        rb_raise(rb_eEOFError, "end of file reached");
    }
    return dst;
}
readlines(*args) click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_readlines(int argc, VALUE *argv, VALUE obj)
{
    VALUE str, dst;
    dst = rb_ary_new();
    while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
        rb_ary_push(dst, str);
    }
    return dst;
}
readpartial(maxlen [, outbuf]) → string, outbuf click to toggle source

Reads at most maxlen bytes from the gziped stream but it blocks only if gzipreader has no data immediately available. If the optional outbuf argument is present, it must reference a String, which will receive the data. It raises EOFError on end of file.

static VALUE
rb_gzreader_readpartial(int argc, VALUE *argv, VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE vlen, outbuf;
    long len;

    rb_scan_args(argc, argv, "11", &vlen, &outbuf);

    len = NUM2INT(vlen);
    if (len < 0) {
        rb_raise(rb_eArgError, "negative length %ld given", len);
    }
    if (!NIL_P(outbuf))
        Check_Type(outbuf, T_STRING);
    return gzfile_readpartial(gz, len, outbuf);
}
rewind() click to toggle source

Resets the position of the file pointer to the point created the GzipReader object. The associated IO object needs to respond to the seek method.

static VALUE
rb_gzreader_rewind(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    gzfile_reader_rewind(gz);
    return INT2FIX(0);
}
tell() click to toggle source

Total number of output bytes output so far.

static VALUE
rb_gzfile_total_out(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    return rb_uint2inum(gz->z.stream.total_out - gz->z.buf_filled);
}
ungetbyte(p1) click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_ungetbyte(VALUE obj, VALUE ch)
{
    struct gzfile *gz = get_gzfile(obj);
    gzfile_ungetbyte(gz, NUM2CHR(ch));
    return Qnil;
}
ungetc(p1) click to toggle source

See Zlib::GzipReader documentation for a description.

static VALUE
rb_gzreader_ungetc(VALUE obj, VALUE s)
{
    struct gzfile *gz;

    if (FIXNUM_P(s))
        return rb_gzreader_ungetbyte(obj, s);
    gz = get_gzfile(obj);
    StringValue(s);
    if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
        s = rb_str_conv_enc(s, rb_enc_get(s), gz->enc2);
    }
    gzfile_ungets(gz, (const Bytef*)RSTRING_PTR(s), RSTRING_LEN(s));
    return Qnil;
}
unused() click to toggle source

Returns the rest of the data which had read for parsing gzip format, or nil if the whole gzip file is not parsed yet.

static VALUE
rb_gzreader_unused(VALUE obj)
{
    struct gzfile *gz;
    Data_Get_Struct(obj, struct gzfile, gz);
    return gzfile_reader_get_unused(gz);
}


class Zlib::GzipWriter - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::GzipWriter

Zlib::GzipWriter is a class for writing gzipped files. GzipWriter should be used with an instance of IO, or IO-like, object.

Following two example generate the same result.

Zlib::GzipWriter.open('hoge.gz') do |gz|
  gz.write 'jugemu jugemu gokou no surikire...'
end

File.open('hoge.gz', 'w') do |f|
  gz = Zlib::GzipWriter.new(f)
  gz.write 'jugemu jugemu gokou no surikire...'
  gz.close
end

To make like gzip(1) does, run following:

orig = 'hoge.txt'
Zlib::GzipWriter.open('hoge.gz') do |gz|
  gz.mtime = File.mtime(orig)
  gz.orig_name = orig
  gz.write IO.binread(orig)
end

NOTE: Due to the limitation of Ruby's finalizer, you must explicitly close GzipWriter objects by Zlib::GzipFile#close etc. Otherwise, GzipWriter will be not able to write the gzip footer and will generate a broken gzip file.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::GzipFile

Public Class Methods

Zlib::GzipWriter.new(io, level = nil, strategy = nil, options = {}) click to toggle source

Creates a GzipWriter object associated with io. level and strategy should be the same as the arguments of Zlib::Deflate.new. The GzipWriter object writes gzipped data to io. io must respond to the write method that behaves the same as IO#write.

The options hash may be used to set the encoding of the data. :external_encoding, :internal_encoding and :encoding may be set as in IO::new.

static VALUE
rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
{
    struct gzfile *gz;
    VALUE io, level, strategy, opt = Qnil;
    int err;

    if (argc > 1) {
        opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
        if (!NIL_P(opt)) argc--;
    }

    rb_scan_args(argc, argv, "12", &io, &level, &strategy);
    Data_Get_Struct(obj, struct gzfile, gz);

    /* this is undocumented feature of zlib */
    gz->level = ARG_LEVEL(level);
    err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
                       -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
    if (err != Z_OK) {
        raise_zlib_error(err, gz->z.stream.msg);
    }
    gz->io = io;
    ZSTREAM_READY(&gz->z);
    rb_gzfile_ecopts(gz, opt);

    if (rb_respond_to(io, id_path)) {
        gz->path = rb_funcall(gz->io, id_path, 0);
        rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
    }

    return obj;
}
Zlib::GzipWriter.open(filename, level=nil, strategy=nil) { |gz| ... } click to toggle source

Opens a file specified by filename for writing gzip compressed data, and returns a GzipWriter object associated with that file. Further details of this method are found in ::new and Zlib::GzipFile.wrap.

static VALUE
rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass)
{
    return gzfile_s_open(argc, argv, klass, "wb");
}

Public Instance Methods

<<(p1) click to toggle source

Document-method: << Same as IO.

#define rb_gzwriter_addstr  rb_io_addstr
comment=(p1) click to toggle source

Specify the comment (str) in the gzip header.

static VALUE
rb_gzfile_set_comment(VALUE obj, VALUE str)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE s;
    char *p;

    if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
        rb_raise(cGzError, "header is already written");
    }
    s = rb_str_dup(rb_str_to_str(str));
    p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
    if (p) {
        rb_str_resize(s, p - RSTRING_PTR(s));
    }
    gz->comment = s;
    return str;
}
flush(flush=nil) click to toggle source

Flushes all the internal buffers of the GzipWriter object. The meaning of flush is same as in Zlib::Deflate#deflate. Zlib::SYNC_FLUSH is used if flush is omitted. It is no use giving flush Zlib::NO_FLUSH.

static VALUE
rb_gzwriter_flush(int argc, VALUE *argv, VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE v_flush;
    int flush;

    rb_scan_args(argc, argv, "01", &v_flush);

    flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
    if (flush != Z_NO_FLUSH) {  /* prevent Z_BUF_ERROR */
        zstream_run(&gz->z, (Bytef*)"", 0, flush);
    }

    gzfile_write_raw(gz);
    if (rb_respond_to(gz->io, id_flush)) {
        rb_funcall(gz->io, id_flush, 0);
    }
    return obj;
}
mtime=(p1) click to toggle source

Specify the modification time (mtime) in the gzip header. Using a Fixnum or Integer

static VALUE
rb_gzfile_set_mtime(VALUE obj, VALUE mtime)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE val;

    if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
        rb_raise(cGzError, "header is already written");
    }

    if (FIXNUM_P(mtime)) {
        gz->mtime = FIX2INT(mtime);
    }
    else {
        val = rb_Integer(mtime);
        gz->mtime = FIXNUM_P(val) ? FIX2UINT(val) : rb_big2ulong(val);
    }
    return mtime;
}
orig_name=(p1) click to toggle source

Specify the original name (str) in the gzip header.

static VALUE
rb_gzfile_set_orig_name(VALUE obj, VALUE str)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE s;
    char *p;

    if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
        rb_raise(cGzError, "header is already written");
    }
    s = rb_str_dup(rb_str_to_str(str));
    p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
    if (p) {
        rb_str_resize(s, p - RSTRING_PTR(s));
    }
    gz->orig_name = s;
    return str;
}
pos() click to toggle source

Total number of input bytes read so far.

static VALUE
rb_gzfile_total_in(VALUE obj)
{
    return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
}
print(*args) click to toggle source

Same as IO.

#define rb_gzwriter_print  rb_io_print
printf(*args) click to toggle source

Same as IO.

#define rb_gzwriter_printf  rb_io_printf
putc(p1) click to toggle source

Same as IO.

static VALUE
rb_gzwriter_putc(VALUE obj, VALUE ch)
{
    struct gzfile *gz = get_gzfile(obj);
    char c = NUM2CHR(ch);

    gzfile_write(gz, (Bytef*)&c, 1);
    return ch;
}
puts(*args) click to toggle source

Same as IO.

#define rb_gzwriter_puts  rb_io_puts
tell() click to toggle source

Total number of input bytes read so far.

static VALUE
rb_gzfile_total_in(VALUE obj)
{
    return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
}
write(p1) click to toggle source

Same as IO.

static VALUE
rb_gzwriter_write(VALUE obj, VALUE str)
{
    struct gzfile *gz = get_gzfile(obj);

    if (!RB_TYPE_P(str, T_STRING))
        str = rb_obj_as_string(str);
    if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
        str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2);
    }
    gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
    return INT2FIX(RSTRING_LEN(str));
}


class Zlib::Inflate - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::Inflate

Zlib:Inflate is the class for decompressing compressed data. Unlike Zlib::Deflate, an instance of this class is not able to duplicate (clone, dup) itself.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::ZStream

Public Class Methods

inflate(string) click to toggle source
Zlib::Inflate.inflate(string)

Decompresses string. Raises a Zlib::NeedDict exception if a preset dictionary is needed for decompression.

This method is almost equivalent to the following code:

def inflate(string)
  zstream = Zlib::Inflate.new
  buf = zstream.inflate(string)
  zstream.finish
  zstream.close
  buf
end

See also Zlib.deflate

static VALUE
rb_inflate_s_inflate(VALUE obj, VALUE src)
{
    struct zstream z;
    VALUE dst, args[2];
    int err;

    StringValue(src);
    zstream_init_inflate(&z);
    err = inflateInit(&z.stream);
    if (err != Z_OK) {
        raise_zlib_error(err, z.stream.msg);
    }
    ZSTREAM_READY(&z);

    args[0] = (VALUE)&z;
    args[1] = src;
    dst = rb_ensure(inflate_run, (VALUE)args, zstream_end, (VALUE)&z);

    OBJ_INFECT(dst, src);
    return dst;
}
Zlib::Inflate.new(window_bits = Zlib::MAX_WBITS) click to toggle source

Creates a new inflate stream for decompression. window_bits sets the size of the history buffer and can have the following values:

0

Have inflate use the window size from the zlib header of the compressed stream.

(8..15)

Overrides the window size of the inflate header in the compressed stream.
The window size must be greater than or equal to the window size of the
compressed stream.
Greater than 15

Add 32 to window_bits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (a Zlib::DataError will be raised for a non-gzip stream).

(-8..-15)

Enables raw deflate mode which will not generate a check value, and will not look for any check values for comparison at the end of the stream.

This is for use with other formats that use the deflate compressed data format such as zip which provide their own check values.

Example

open "compressed.file" do |compressed_io|
  inflate = Zlib::Inflate.new(Zlib::MAX_WBITS + 32)

  begin
    open "uncompressed.file", "w+" do |uncompressed_io|
      uncompressed_io << zi.inflate(compressed_io.read)
    }
  ensure
    zi.close
  end
end

static VALUE
rb_inflate_initialize(int argc, VALUE *argv, VALUE obj)
{
    struct zstream *z;
    VALUE wbits;
    int err;

    rb_scan_args(argc, argv, "01", &wbits);
    Data_Get_Struct(obj, struct zstream, z);

    err = inflateInit2(&z->stream, ARG_WBITS(wbits));
    if (err != Z_OK) {
        raise_zlib_error(err, z->stream.msg);
    }
    ZSTREAM_READY(z);

    return obj;
}

Public Instance Methods

<<(p1) click to toggle source

Same as IO.

static VALUE
rb_inflate_addstr(VALUE obj, VALUE src)
{
    struct zstream *z = get_zstream(obj);

    OBJ_INFECT(obj, src);

    if (ZSTREAM_IS_FINISHED(z)) {
        if (!NIL_P(src)) {
            StringValue(src);
            zstream_append_buffer2(z, src);
        }
    }
    else {
        do_inflate(z, src);
        if (ZSTREAM_IS_FINISHED(z)) {
            zstream_passthrough_input(z);
        }
    }

    return obj;
}
add_dictionary(string) click to toggle source

Provide the inflate stream with a dictionary that may be required in the future. Multiple dictionaries may be provided. The inflate stream will automatically choose the correct user-provided dictionary based on the stream's required dictionary.

static VALUE
rb_inflate_add_dictionary(VALUE obj, VALUE dictionary) {
    VALUE dictionaries = rb_ivar_get(obj, id_dictionaries);
    VALUE checksum = do_checksum(1, &dictionary, adler32);

    rb_hash_aset(dictionaries, checksum, dictionary);

    return obj;
}
inflate(deflate_string) → String click to toggle source
inflate(deflate_string) { |chunk| ... } → nil

Inputs deflate_string into the inflate stream and returns the output from the stream. Calling this method, both the input and the output buffer of the stream are flushed. If string is nil, this method finishes the stream, just like Zlib::ZStream#finish.

If a block is given consecutive inflated chunks from the deflate_string are yielded to the block and nil is returned.

Raises a Zlib::NeedDict exception if a preset dictionary is needed to decompress. Set the dictionary by #set_dictionary and then call this method again with an empty string to flush the stream:

inflater = Zlib::Inflate.new

begin
  out = inflater.inflate compressed
rescue Zlib::NeedDict
  # ensure the dictionary matches the stream's required dictionary
  raise unless inflater.adler == Zlib.adler32(dictionary)

  inflater.set_dictionary dictionary
  inflater.inflate ''
end

# ...

inflater.close

See also ::new

static VALUE
rb_inflate_inflate(VALUE obj, VALUE src)
{
    struct zstream *z = get_zstream(obj);
    VALUE dst;

    OBJ_INFECT(obj, src);

    if (ZSTREAM_IS_FINISHED(z)) {
        if (NIL_P(src)) {
            dst = zstream_detach_buffer(z);
        }
        else {
            StringValue(src);
            zstream_append_buffer2(z, src);
            dst = rb_str_new(0, 0);
            OBJ_INFECT(dst, obj);
        }
    }
    else {
        do_inflate(z, src);
        dst = zstream_detach_buffer(z);
        if (ZSTREAM_IS_FINISHED(z)) {
            zstream_passthrough_input(z);
        }
    }

    return dst;
}
set_dictionary(p1) click to toggle source

Sets the preset dictionary and returns string. This method is available just only after a Zlib::NeedDict exception was raised. See zlib.h for details.

static VALUE
rb_inflate_set_dictionary(VALUE obj, VALUE dic)
{
    struct zstream *z = get_zstream(obj);
    VALUE src = dic;
    int err;

    OBJ_INFECT(obj, dic);
    StringValue(src);
    err = inflateSetDictionary(&z->stream,
                               (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
    if (err != Z_OK) {
        raise_zlib_error(err, z->stream.msg);
    }

    return dic;
}
sync(string) click to toggle source

Inputs string into the end of input buffer and skips data until a full flush point can be found. If the point is found in the buffer, this method flushes the buffer and returns false. Otherwise it returns true and the following data of full flush point is preserved in the buffer.

static VALUE
rb_inflate_sync(VALUE obj, VALUE src)
{
    struct zstream *z = get_zstream(obj);

    OBJ_INFECT(obj, src);
    StringValue(src);
    return zstream_sync(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src));
}
sync_point?() click to toggle source

Quoted verbatim from original documentation:

What is this?

:)

static VALUE
rb_inflate_sync_point_p(VALUE obj)
{
    struct zstream *z = get_zstream(obj);
    int err;

    err = inflateSyncPoint(&z->stream);
    if (err == 1) {
        return Qtrue;
    }
    if (err != Z_OK) {
        raise_zlib_error(err, z->stream.msg);
    }
    return Qfalse;
}


class Zlib::MemError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::MemError

Subclass of Zlib::Error

When zlib returns a Z_MEM_ERROR, usually if there was not enough memory.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::Error


class Zlib::NeedDict - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::NeedDict

Subclass of Zlib::Error

When zlib returns a Z_NEED_DICT if a preset dictionary is needed at this point.

Used by Zlib::Inflate.inflate and Zlib.inflate

In Files

  • ext/zlib/zlib.c

Parent

Zlib::Error


class Zlib::StreamEnd - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::StreamEnd

Subclass of Zlib::Error

When zlib returns a Z_STREAM_END is return if the end of the compressed data has been reached and all uncompressed out put has been produced.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::Error


class Zlib::StreamError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::StreamError

Subclass of Zlib::Error

When zlib returns a Z_STREAM_ERROR, usually if the stream state was inconsistent.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::Error


class Zlib::VersionError - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::VersionError

Subclass of Zlib::Error

When zlib returns a Z_VERSION_ERROR, usually if the zlib library version is incompatible with the version assumed by the caller.

In Files

  • ext/zlib/zlib.c

Parent

Zlib::Error


class Zlib::ZStream - Ruby 2.0.0-p576 Standard Library API Reference API Reference

class Zlib::ZStream

Zlib::ZStream is the abstract class for the stream which handles the compressed data. The operations are defined in the subclasses: Zlib::Deflate for compression, and Zlib::Inflate for decompression.

An instance of Zlib::ZStream has one stream (struct zstream in the source) and two variable-length buffers which associated to the input (next_in) of the stream and the output (next_out) of the stream. In this document, “input buffer” means the buffer for input, and “output buffer” means the buffer for output.

Data input into an instance of Zlib::ZStream are temporally stored into the end of input buffer, and then data in input buffer are processed from the beginning of the buffer until no more output from the stream is produced (i.e. until #avail_out > 0 after processing). During processing, output buffer is allocated and expanded automatically to hold all output data.

Some particular instance methods consume the data in output buffer and return them as a String.

Here is an ascii art for describing above:

+================ an instance of Zlib::ZStream ================+
||                                                            ||
||     +--------+          +-------+          +--------+      ||
||  +--| output |<---------|zstream|<---------| input  |<--+  ||
||  |  | buffer |  next_out+-------+next_in   | buffer |   |  ||
||  |  +--------+                             +--------+   |  ||
||  |                                                      |  ||
+===|======================================================|===+
    |                                                      |
    v                                                      |
"output data"                                         "input data"

If an error occurs during processing input buffer, an exception which is a subclass of Zlib::Error is raised. At that time, both input and output buffer keep their conditions at the time when the error occurs.

Method Catalogue

Many of the methods in this class are fairly low-level and unlikely to be of interest to users. In fact, users are unlikely to use this class directly; rather they will be interested in Zlib::Inflate and Zlib::Deflate.

The higher level methods are listed below.

  • total_in

  • total_out

  • data_type

  • adler

  • reset

  • finish

  • finished?

  • close

  • closed?

In Files

  • ext/zlib/zlib.c

Parent

Object

Public Instance Methods

adler() click to toggle source

Returns the adler-32 checksum.

static VALUE
rb_zstream_adler(VALUE obj)
{
        return rb_uint2inum(get_zstream(obj)->stream.adler);
}
avail_in() click to toggle source

Returns bytes of data in the input buffer. Normally, returns 0.

static VALUE
rb_zstream_avail_in(VALUE obj)
{
    struct zstream *z;
    Data_Get_Struct(obj, struct zstream, z);
    return INT2FIX(NIL_P(z->input) ? 0 : (int)(RSTRING_LEN(z->input)));
}
avail_out() click to toggle source

Returns number of bytes of free spaces in output buffer. Because the free space is allocated automatically, this method returns 0 normally.

static VALUE
rb_zstream_avail_out(VALUE obj)
{
    struct zstream *z;
    Data_Get_Struct(obj, struct zstream, z);
    return rb_uint2inum(z->stream.avail_out);
}
avail_out=(p1) click to toggle source

Allocates size bytes of free space in the output buffer. If there are more than size bytes already in the buffer, the buffer is truncated. Because free space is allocated automatically, you usually don't need to use this method.

static VALUE
rb_zstream_set_avail_out(VALUE obj, VALUE size)
{
    struct zstream *z = get_zstream(obj);

    Check_Type(size, T_FIXNUM);
    zstream_expand_buffer_into(z, FIX2INT(size));
    return size;
}
close() click to toggle source

Closes the stream. All operations on the closed stream will raise an exception.

static VALUE
rb_zstream_end(VALUE obj)
{
    zstream_end(get_zstream(obj));
    return Qnil;
}
closed?() click to toggle source

Returns true if the stream is closed.

static VALUE
rb_zstream_closed_p(VALUE obj)
{
    struct zstream *z;
    Data_Get_Struct(obj, struct zstream, z);
    return ZSTREAM_IS_READY(z) ? Qfalse : Qtrue;
}
data_type() click to toggle source

Guesses the type of the data which have been inputed into the stream. The returned value is either BINARY, ASCII, or UNKNOWN.

static VALUE
rb_zstream_data_type(VALUE obj)
{
    return INT2FIX(get_zstream(obj)->stream.data_type);
}
end() click to toggle source

Closes the stream. All operations on the closed stream will raise an exception.

static VALUE
rb_zstream_end(VALUE obj)
{
    zstream_end(get_zstream(obj));
    return Qnil;
}
ended?() click to toggle source

Returns true if the stream is closed.

static VALUE
rb_zstream_closed_p(VALUE obj)
{
    struct zstream *z;
    Data_Get_Struct(obj, struct zstream, z);
    return ZSTREAM_IS_READY(z) ? Qfalse : Qtrue;
}
finish → String click to toggle source
finish { |chunk| ... } → nil

Finishes the stream and flushes output buffer. If a block is given each chunk is yielded to the block until the input buffer has been flushed to the output buffer.

static VALUE
rb_zstream_finish(VALUE obj)
{
    struct zstream *z = get_zstream(obj);

    zstream_run(z, (Bytef*)"", 0, Z_FINISH);

    return zstream_detach_buffer(z);
}
finished?() click to toggle source

Returns true if the stream is finished.

static VALUE
rb_zstream_finished_p(VALUE obj)
{
    return ZSTREAM_IS_FINISHED(get_zstream(obj)) ? Qtrue : Qfalse;
}
flush_next_out → String click to toggle source
flush_next_out { |chunk| ... } → nil

Flushes output buffer and returns all data in that buffer. If a block is given each chunk is yielded to the block until the current output buffer has been flushed.

static VALUE
rb_zstream_flush_next_in(VALUE obj)
{
    struct zstream *z;
    VALUE dst;

    Data_Get_Struct(obj, struct zstream, z);
    dst = zstream_detach_input(z);
    OBJ_INFECT(dst, obj);
    return dst;
}
flush_next_out() click to toggle source

Flushes output buffer and returns all data in that buffer.

static VALUE
rb_zstream_flush_next_out(VALUE obj)
{
    struct zstream *z;

    Data_Get_Struct(obj, struct zstream, z);

    return zstream_detach_buffer(z);
}
reset() click to toggle source

Resets and initializes the stream. All data in both input and output buffer are discarded.

static VALUE
rb_zstream_reset(VALUE obj)
{
    zstream_reset(get_zstream(obj));
    return Qnil;
}
stream_end?() click to toggle source

Returns true if the stream is finished.

static VALUE
rb_zstream_finished_p(VALUE obj)
{
    return ZSTREAM_IS_FINISHED(get_zstream(obj)) ? Qtrue : Qfalse;
}
total_in() click to toggle source

Returns the total bytes of the input data to the stream. FIXME

static VALUE
rb_zstream_total_in(VALUE obj)
{
    return rb_uint2inum(get_zstream(obj)->stream.total_in);
}
total_out() click to toggle source

Returns the total bytes of the output data from the stream. FIXME

static VALUE
rb_zstream_total_out(VALUE obj)
{
    return rb_uint2inum(get_zstream(obj)->stream.total_out);
}


LICENSE - Ruby 2.0.0-p576 Standard Library API Reference API Reference

Ruby 2.0.0-p576 Standard Library API Reference API Reference

This is the API documentation for 'Ruby 2.0.0-p576 Standard Library API Reference API Reference'.

Files

  • grammar.en.rdoc
  • LICENSE.txt


grammar.en - Ruby 2.0.0-p576 Standard Library API Reference API Reference

Racc Grammar File Reference

Global Structure

Class Block and User Code Block

There are two blocks on toplevel. One is 'class' block, another is 'user code' block. 'user code' block MUST be placed after 'class' block.

Comments

You can insert comments about all places. Two style comments can be used, Ruby style '#.….' and C style '/*.…..*/'.

Class Block

The class block is formed like this:

class CLASS_NAME
  [precedance table]
  [token declarations]
  [expected number of S/R conflicts]
  [options]
  [semantic value convertion]
  [start rule]
rule
  GRAMMARS

CLASS_NAME is a name of parser class. This is the name of generating parser class.

If CLASS_NAME includes '::', Racc outputs module clause. For example, writing “class M::C” causes creating the code bellow:

module M
  class C
    :
    :
  end
end

Grammar Block

The grammar block describes grammar which is able to be understood by parser. Syntax is:

(token): (token) (token) (token).... (action)

(token): (token) (token) (token).... (action)
       | (token) (token) (token).... (action)
       | (token) (token) (token).... (action)

(action) is an action which is executed when its (token)s are found. (action) is a ruby code block, which is surrounded by braces:

{ print val[0]
  puts val[1] }

Note that you cannot use '%' string, here document, '%r' regexp in action.

Actions can be omitted. When it is omitted, '' (empty string) is used.

A return value of action is a value of left side value ($$). It is value of result, or returned value by `return` statement.

Here is an example of whole grammar block.

rule
  goal: definition rules source { result = val }

  definition:    none      { result = [] }
    | definition startdesig  { result[0] = val[1] }
    | definition
             precrule   # this line continues from upper line
      {
        result[1] = val[1]
      }

  startdesig: START TOKEN

You can use the following special local variables in action:

result ($$)

The value of left-hand side (lhs). A default value is val.

val ($1,$2,$3...)

An array of value of right-hand side (rhs).

_values (...$-2,$-1,$0)

A stack of values. DO NOT MODIFY this stack unless you know what you are doing.

Operator Precedance

This function is equal to '%prec' in yacc. To designate this block:

prechigh
  nonassoc '++'
  left     '*' '/'
  left     '+' '-'
  right    '='
preclow

`right` is yacc's %right, `left` is yacc's %left.

`=` + (symbol) means yacc's %prec:

prechigh
  nonassoc UMINUS
  left '*' '/'
  left '+' '-'
preclow

rule
  exp: exp '*' exp
     | exp '-' exp
     | '-' exp       =UMINUS   # equals to "%prec UMINUS"
         :
         :

expect

Racc has bison's “expect” directive.

# Example

class MyParser
rule
  expect 3
    :
    :

This directive declares “expected” number of shift/reduce conflicts. If “expected” number is equal to real number of conflicts, Racc does not print conflict warning message.

Declaring Tokens

By declaring tokens, you can avoid many meaningless bugs. If declared token does not exist or existing token does not decleared, Racc output warnings. Declaration syntax is:

token TOKEN_NAME AND_IS_THIS
      ALSO_THIS_IS AGAIN_AND_AGAIN THIS_IS_LAST

Options

You can write options for Racc command in your Racc file.

options OPTION OPTION ...

Options are:

omit_action_call

omits empty action call or not.

result_var

uses local variable “result” or not.

You can use 'no_' prefix to invert their meanings.

Converting Token Symbol

Token symbols are, as default,

naked token string in Racc file (TOK, XFILE, this_is_token, ...)
--> symbol (:TOK, :XFILE, :this_is_token, ...)
quoted string (':', '.', '(', ...)
--> same string (':', '.', '(', ...)

You can change this default by “convert” block. Here is an example:

convert
  PLUS 'PlusClass'      # We use PlusClass for symbol of `PLUS'
  MIN  'MinusClass'     # We use MinusClass for symbol of `MIN'
end

We can use almost all ruby value can be used by token symbol, except 'false' and 'nil'. These cause unexpected parse error.

If you want to use String as token symbol, special care is required. For example:

convert
  class '"cls"'            # in code, "cls"
  PLUS '"plus\n"'          # in code, "plus\n"
  MIN  "\"minus#{val}\""   # in code, \"minus#{val}\"
end

Start Rule

'%start' in yacc. This changes start rule.

start real_target

User Code Block

“User Code Block” is a Ruby source code which is copied to output. There are three user code blocks, “header” “inner” and “footer”.

Format of user code is like this:

---- header
  ruby statement
  ruby statement
  ruby statement

---- inner
  ruby statement
     :
     :

If four '-' exist on line head, Racc treat it as beginning of user code block. The name of user code block must be one word.


LICENSE - Ruby 2.0.0-p576 Standard Library API Reference API Reference

RubyGems is copyrighted free software by Chad Fowler, Rich Kilmer, Jim Weirich and others. You can redistribute it and/or modify it under either the terms of the GPL (see the GPL.txt file), or the conditions below:

1. You may make and give away verbatim copies of the source form of the
   software without restriction, provided that you duplicate all of the
   original copyright notices and associated disclaimers.

2. You may modify your copy of the software in any way, provided that
   you do at least ONE of the following:

     a) place your modifications in the Public Domain or otherwise
        make them Freely Available, such as by posting said
        modifications to Usenet or an equivalent medium, or by allowing
        the author to include your modifications in the software.

     b) use the modified software only within your corporation or
        organization.

     c) rename any non-standard executables so the names do not conflict
        with standard executables, which must also be provided.

     d) make other distribution arrangements with the author.

3. You may distribute the software in object code or executable
   form, provided that you do at least ONE of the following:

     a) distribute the executables and library files of the software,
        together with instructions (in the manual page or equivalent)
        on where to get the original distribution.

     b) accompany the distribution with the machine-readable source of
        the software.

     c) give non-standard executables non-standard names, with
        instructions on where to get the original software distribution.

     d) make other distribution arrangements with the author.

4. You may modify and include the part of the software into any other
   software (possibly commercial).

5. The scripts and library files supplied as input to or produced as
   output from the software do not automatically fall under the
   copyright of the software, but belong to whomever generated them,
   and may be sold commercially, and may be aggregated with this
   software.

6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
   IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   PURPOSE.


Ruby 2.0.0-p576 Standard Library API Reference API Reference

This is the API documentation for 'Ruby 2.0.0-p576 Standard Library API Reference API Reference'.

Files

  • grammar.en.rdoc
  • LICENSE.txt

Classes/Modules

  • RSS
  • RSS::Atom
  • RSS::Atom::CommonModel
  • RSS::Atom::ContentModel
  • RSS::Atom::ContentModel::ClassMethods
  • RSS::Atom::DateConstruct
  • RSS::Atom::DuplicateLinkChecker
  • RSS::Atom::Entry
  • RSS::Atom::Feed
  • RSS::Atom::Feed::Author
  • RSS::Atom::Feed::Category
  • RSS::Atom::Feed::Contributor
  • RSS::Atom::Feed::Entry
  • RSS::Atom::Feed::Entry::Content
  • RSS::Atom::Feed::Entry::Published
  • RSS::Atom::Feed::Entry::Source
  • RSS::Atom::Feed::Entry::Summary
  • RSS::Atom::Feed::Generator
  • RSS::Atom::Feed::Icon
  • RSS::Atom::Feed::Id
  • RSS::Atom::Feed::Link
  • RSS::Atom::Feed::Logo
  • RSS::Atom::Feed::Rights
  • RSS::Atom::Feed::Subtitle
  • RSS::Atom::Feed::Title
  • RSS::Atom::Feed::Updated
  • RSS::Atom::PersonConstruct
  • RSS::Atom::PersonConstruct::Email
  • RSS::Atom::PersonConstruct::Name
  • RSS::Atom::PersonConstruct::Uri
  • RSS::Atom::TextConstruct
  • RSS::Atom::URIContentModel
  • RSS::BaseDublinCoreModel
  • RSS::BaseListener
  • RSS::BaseModel
  • RSS::BaseParser
  • RSS::BaseTrackBackModel
  • RSS::ContentModel
  • RSS::ConversionError
  • RSS::Converter
  • RSS::DublinCoreModel
  • RSS::DublincoreModel
  • RSS::Element
  • RSS::Error
  • RSS::ITunesBaseModel
  • RSS::ITunesChannelModel
  • RSS::ITunesChannelModel::ITunesCategory
  • RSS::ITunesChannelModel::ITunesImage
  • RSS::ITunesChannelModel::ITunesOwner
  • RSS::ITunesItemModel
  • RSS::ITunesItemModel::ITunesDuration
  • RSS::ITunesModelUtils
  • RSS::ImageFaviconModel
  • RSS::ImageFaviconModel::ImageFavicon
  • RSS::ImageItemModel
  • RSS::ImageItemModel::ImageItem
  • RSS::ImageModelUtils
  • RSS::InvalidRSSError
  • RSS::ListenerMixin
  • RSS::Maker
  • RSS::Maker::Atom
  • RSS::Maker::Atom::Entry
  • RSS::Maker::Atom::Entry::Channel
  • RSS::Maker::Atom::Entry::Channel::Cloud
  • RSS::Maker::Atom::Entry::Channel::Description
  • RSS::Maker::Atom::Entry::Channel::Generator
  • RSS::Maker::Atom::Entry::Channel::SkipDays
  • RSS::Maker::Atom::Entry::Channel::SkipDays::Day
  • RSS::Maker::Atom::Entry::Channel::SkipHours
  • RSS::Maker::Atom::Entry::Channel::SkipHours::Hour
  • RSS::Maker::Atom::Entry::Image
  • RSS::Maker::Atom::Entry::Items
  • RSS::Maker::Atom::Entry::Items::Item
  • RSS::Maker::Atom::Entry::Textinput
  • RSS::Maker::Atom::Feed
  • RSS::Maker::Atom::Feed::Channel
  • RSS::Maker::Atom::Feed::Channel::Categories
  • RSS::Maker::Atom::Feed::Channel::Categories::Category
  • RSS::Maker::Atom::Feed::Channel::Cloud
  • RSS::Maker::Atom::Feed::Channel::Generator
  • RSS::Maker::Atom::Feed::Channel::Links
  • RSS::Maker::Atom::Feed::Channel::Links::Link
  • RSS::Maker::Atom::Feed::Channel::SkipDays
  • RSS::Maker::Atom::Feed::Channel::SkipDays::Day
  • RSS::Maker::Atom::Feed::Channel::SkipHours
  • RSS::Maker::Atom::Feed::Channel::SkipHours::Hour
  • RSS::Maker::Atom::Feed::Image
  • RSS::Maker::Atom::Feed::Items
  • RSS::Maker::Atom::Feed::Items::Item
  • RSS::Maker::Atom::Feed::Items::Item::Categories
  • RSS::Maker::Atom::Feed::Items::Item::Categories::Category
  • RSS::Maker::Atom::Feed::Items::Item::Content
  • RSS::Maker::Atom::Feed::Items::Item::Enclosure
  • RSS::Maker::Atom::Feed::Items::Item::Guid
  • RSS::Maker::Atom::Feed::Items::Item::Links
  • RSS::Maker::Atom::Feed::Items::Item::Links::Link
  • RSS::Maker::Atom::Feed::Items::Item::Source
  • RSS::Maker::Atom::Feed::Items::Item::Source::Categories
  • RSS::Maker::Atom::Feed::Items::Item::Source::Categories::Category
  • RSS::Maker::Atom::Feed::Items::Item::Source::Generator
  • RSS::Maker::Atom::Feed::Items::Item::Source::Icon
  • RSS::Maker::Atom::Feed::Items::Item::Source::Links
  • RSS::Maker::Atom::Feed::Items::Item::Source::Links::Link
  • RSS::Maker::Atom::Feed::Items::Item::Source::Logo
  • RSS::Maker::Atom::Feed::Textinput
  • RSS::Maker::AtomCategory
  • RSS::Maker::AtomGenerator
  • RSS::Maker::AtomLink
  • RSS::Maker::AtomLogo
  • RSS::Maker::AtomPersonConstructBase
  • RSS::Maker::AtomPersons
  • RSS::Maker::AtomTextConstruct
  • RSS::Maker::AtomTextConstructBase
  • RSS::Maker::AtomTextConstructBase::EnsureXMLContent
  • RSS::Maker::Base
  • RSS::Maker::ChannelBase
  • RSS::Maker::ChannelBase::AuthorsBase
  • RSS::Maker::ChannelBase::AuthorsBase::AuthorBase
  • RSS::Maker::ChannelBase::CategoriesBase
  • RSS::Maker::ChannelBase::CategoriesBase::CategoryBase
  • RSS::Maker::ChannelBase::CloudBase
  • RSS::Maker::ChannelBase::ContributorsBase
  • RSS::Maker::ChannelBase::ContributorsBase::ContributorBase
  • RSS::Maker::ChannelBase::CopyrightBase
  • RSS::Maker::ChannelBase::DescriptionBase
  • RSS::Maker::ChannelBase::GeneratorBase
  • RSS::Maker::ChannelBase::ITunesCategories
  • RSS::Maker::ChannelBase::ITunesCategories::ITunesCategory
  • RSS::Maker::ChannelBase::ITunesImage
  • RSS::Maker::ChannelBase::ITunesOwner
  • RSS::Maker::ChannelBase::LinksBase
  • RSS::Maker::ChannelBase::LinksBase::LinkBase
  • RSS::Maker::ChannelBase::SkipDaysBase
  • RSS::Maker::ChannelBase::SkipDaysBase::DayBase
  • RSS::Maker::ChannelBase::SkipHoursBase
  • RSS::Maker::ChannelBase::SkipHoursBase::HourBase
  • RSS::Maker::ChannelBase::TitleBase
  • RSS::Maker::ContentModel
  • RSS::Maker::DublinCoreModel
  • RSS::Maker::ITunesBaseModel
  • RSS::Maker::ITunesChannelModel
  • RSS::Maker::ITunesChannelModel::ITunesCategoriesBase
  • RSS::Maker::ITunesChannelModel::ITunesCategoriesBase::ITunesCategoryBase
  • RSS::Maker::ITunesChannelModel::ITunesImageBase
  • RSS::Maker::ITunesChannelModel::ITunesOwnerBase
  • RSS::Maker::ITunesItemModel
  • RSS::Maker::ITunesItemModel::ITunesDurationBase
  • RSS::Maker::ImageBase
  • RSS::Maker::ImageFaviconModel
  • RSS::Maker::ImageFaviconModel::ImageFaviconBase
  • RSS::Maker::ImageItemModel
  • RSS::Maker::ImageItemModel::ImageItemBase
  • RSS::Maker::ItemsBase
  • RSS::Maker::ItemsBase::ItemBase
  • RSS::Maker::ItemsBase::ItemBase::ContentBase
  • RSS::Maker::ItemsBase::ItemBase::DescriptionBase
  • RSS::Maker::ItemsBase::ItemBase::EnclosureBase
  • RSS::Maker::ItemsBase::ItemBase::GuidBase
  • RSS::Maker::ItemsBase::ItemBase::ITunesDuration
  • RSS::Maker::ItemsBase::ItemBase::RightsBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase::IconBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase::LogoBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase::RightsBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase::SubtitleBase
  • RSS::Maker::ItemsBase::ItemBase::SourceBase::TitleBase
  • RSS::Maker::ItemsBase::ItemBase::TitleBase
  • RSS::Maker::RSS09
  • RSS::Maker::RSS091
  • RSS::Maker::RSS091::Channel
  • RSS::Maker::RSS091::Image
  • RSS::Maker::RSS091::Items
  • RSS::Maker::RSS091::Items::Item
  • RSS::Maker::RSS091::Textinput
  • RSS::Maker::RSS092
  • RSS::Maker::RSS092::Channel
  • RSS::Maker::RSS092::Image
  • RSS::Maker::RSS092::Items
  • RSS::Maker::RSS092::Items::Item
  • RSS::Maker::RSS092::Textinput
  • RSS::Maker::RSS09::Channel
  • RSS::Maker::RSS09::Channel::Authors
  • RSS::Maker::RSS09::Channel::Authors::Author
  • RSS::Maker::RSS09::Channel::Categories
  • RSS::Maker::RSS09::Channel::Categories::Category
  • RSS::Maker::RSS09::Channel::Cloud
  • RSS::Maker::RSS09::Channel::Contributors
  • RSS::Maker::RSS09::Channel::Contributors::Contributor
  • RSS::Maker::RSS09::Channel::Copyright
  • RSS::Maker::RSS09::Channel::Description
  • RSS::Maker::RSS09::Channel::Generator
  • RSS::Maker::RSS09::Channel::Links
  • RSS::Maker::RSS09::Channel::Links::Link
  • RSS::Maker::RSS09::Channel::SkipDays
  • RSS::Maker::RSS09::Channel::SkipDays::Day
  • RSS::Maker::RSS09::Channel::SkipHours
  • RSS::Maker::RSS09::Channel::SkipHours::Hour
  • RSS::Maker::RSS09::Channel::Title
  • RSS::Maker::RSS09::Image
  • RSS::Maker::RSS09::Items
  • RSS::Maker::RSS09::Items::Item
  • RSS::Maker::RSS09::Items::Item::Authors
  • RSS::Maker::RSS09::Items::Item::Authors::Author
  • RSS::Maker::RSS09::Items::Item::Categories
  • RSS::Maker::RSS09::Items::Item::Categories::Category
  • RSS::Maker::RSS09::Items::Item::Content
  • RSS::Maker::RSS09::Items::Item::Contributors
  • RSS::Maker::RSS09::Items::Item::Contributors::Contributor
  • RSS::Maker::RSS09::Items::Item::Description
  • RSS::Maker::RSS09::Items::Item::Enclosure
  • RSS::Maker::RSS09::Items::Item::Guid
  • RSS::Maker::RSS09::Items::Item::Links
  • RSS::Maker::RSS09::Items::Item::Links::Link
  • RSS::Maker::RSS09::Items::Item::Rights
  • RSS::Maker::RSS09::Items::Item::Source
  • RSS::Maker::RSS09::Items::Item::Source::Authors
  • RSS::Maker::RSS09::Items::Item::Source::Authors::Author
  • RSS::Maker::RSS09::Items::Item::Source::Categories
  • RSS::Maker::RSS09::Items::Item::Source::Categories::Category
  • RSS::Maker::RSS09::Items::Item::Source::Contributors
  • RSS::Maker::RSS09::Items::Item::Source::Contributors::Contributor
  • RSS::Maker::RSS09::Items::Item::Source::Generator
  • RSS::Maker::RSS09::Items::Item::Source::Icon
  • RSS::Maker::RSS09::Items::Item::Source::Links
  • RSS::Maker::RSS09::Items::Item::Source::Links::Link
  • RSS::Maker::RSS09::Items::Item::Source::Logo
  • RSS::Maker::RSS09::Items::Item::Source::Rights
  • RSS::Maker::RSS09::Items::Item::Source::Subtitle
  • RSS::Maker::RSS09::Items::Item::Source::Title
  • RSS::Maker::RSS09::Items::Item::Title
  • RSS::Maker::RSS09::Textinput
  • RSS::Maker::RSS10
  • RSS::Maker::RSS10::Channel
  • RSS::Maker::RSS10::Channel::Authors
  • RSS::Maker::RSS10::Channel::Authors::Author
  • RSS::Maker::RSS10::Channel::Categories
  • RSS::Maker::RSS10::Channel::Categories::Category
  • RSS::Maker::RSS10::Channel::Cloud
  • RSS::Maker::RSS10::Channel::Contributors
  • RSS::Maker::RSS10::Channel::Contributors::Contributor
  • RSS::Maker::RSS10::Channel::Copyright
  • RSS::Maker::RSS10::Channel::Description
  • RSS::Maker::RSS10::Channel::Generator
  • RSS::Maker::RSS10::Channel::Links
  • RSS::Maker::RSS10::Channel::Links::Link
  • RSS::Maker::RSS10::Channel::SkipDays
  • RSS::Maker::RSS10::Channel::SkipDays::Day
  • RSS::Maker::RSS10::Channel::SkipHours
  • RSS::Maker::RSS10::Channel::SkipHours::Hour
  • RSS::Maker::RSS10::Channel::Title
  • RSS::Maker::RSS10::Image
  • RSS::Maker::RSS10::Items
  • RSS::Maker::RSS10::Items::Item
  • RSS::Maker::RSS10::Items::Item::Authors
  • RSS::Maker::RSS10::Items::Item::Authors::Author
  • RSS::Maker::RSS10::Items::Item::Categories
  • RSS::Maker::RSS10::Items::Item::Categories::Category
  • RSS::Maker::RSS10::Items::Item::Content
  • RSS::Maker::RSS10::Items::Item::Contributors
  • RSS::Maker::RSS10::Items::Item::Contributors::Contributor
  • RSS::Maker::RSS10::Items::Item::Description
  • RSS::Maker::RSS10::Items::Item::Enclosure
  • RSS::Maker::RSS10::Items::Item::Guid
  • RSS::Maker::RSS10::Items::Item::Links
  • RSS::Maker::RSS10::Items::Item::Links::Link
  • RSS::Maker::RSS10::Items::Item::Rights
  • RSS::Maker::RSS10::Items::Item::Source
  • RSS::Maker::RSS10::Items::Item::Source::Authors
  • RSS::Maker::RSS10::Items::Item::Source::Authors::Author
  • RSS::Maker::RSS10::Items::Item::Source::Categories
  • RSS::Maker::RSS10::Items::Item::Source::Categories::Category
  • RSS::Maker::RSS10::Items::Item::Source::Contributors
  • RSS::Maker::RSS10::Items::Item::Source::Contributors::Contributor
  • RSS::Maker::RSS10::Items::Item::Source::Generator
  • RSS::Maker::RSS10::Items::Item::Source::Icon
  • RSS::Maker::RSS10::Items::Item::Source::Links
  • RSS::Maker::RSS10::Items::Item::Source::Links::Link
  • RSS::Maker::RSS10::Items::Item::Source::Logo
  • RSS::Maker::RSS10::Items::Item::Source::Rights
  • RSS::Maker::RSS10::Items::Item::Source::Subtitle
  • RSS::Maker::RSS10::Items::Item::Source::Title
  • RSS::Maker::RSS10::Items::Item::Title
  • RSS::Maker::RSS10::Textinput
  • RSS::Maker::RSS20
  • RSS::Maker::RSS20::Channel
  • RSS::Maker::RSS20::Channel::Categories
  • RSS::Maker::RSS20::Channel::Categories::Category
  • RSS::Maker::RSS20::Channel::Cloud
  • RSS::Maker::RSS20::Channel::Generator
  • RSS::Maker::RSS20::Channel::SkipDays
  • RSS::Maker::RSS20::Channel::SkipDays::Day
  • RSS::Maker::RSS20::Channel::SkipHours
  • RSS::Maker::RSS20::Channel::SkipHours::Hour
  • RSS::Maker::RSS20::Image
  • RSS::Maker::RSS20::Items
  • RSS::Maker::RSS20::Items::Item
  • RSS::Maker::RSS20::Items::Item::Authors
  • RSS::Maker::RSS20::Items::Item::Authors::Author
  • RSS::Maker::RSS20::Items::Item::Categories
  • RSS::Maker::RSS20::Items::Item::Categories::Category
  • RSS::Maker::RSS20::Items::Item::Enclosure
  • RSS::Maker::RSS20::Items::Item::Guid
  • RSS::Maker::RSS20::Items::Item::Source
  • RSS::Maker::RSS20::Items::Item::Source::Links
  • RSS::Maker::RSS20::Items::Item::Source::Links::Link
  • RSS::Maker::RSS20::Textinput
  • RSS::Maker::RSSBase
  • RSS::Maker::SetupDefaultDate
  • RSS::Maker::SetupDefaultLanguage
  • RSS::Maker::SlashModel
  • RSS::Maker::SyndicationModel
  • RSS::Maker::TaxonomyTopicModel
  • RSS::Maker::TaxonomyTopicModel::TaxonomyTopicsBase
  • RSS::Maker::TaxonomyTopicModel::TaxonomyTopicsBase::TaxonomyTopicBase
  • RSS::Maker::TaxonomyTopicsModel
  • RSS::Maker::TaxonomyTopicsModel::TaxonomyTopicsBase
  • RSS::Maker::TextinputBase
  • RSS::Maker::TrackBackModel
  • RSS::Maker::TrackBackModel::TrackBackAboutsBase
  • RSS::Maker::TrackBackModel::TrackBackAboutsBase::TrackBackAboutBase
  • RSS::Maker::XMLStyleSheets
  • RSS::Maker::XMLStyleSheets::XMLStyleSheet
  • RSS::MissingAttributeError
  • RSS::MissingTagError
  • RSS::NSError
  • RSS::NotAvailableValueError
  • RSS::NotExceptedTagError
  • RSS::NotExpectedTagError
  • RSS::NotSetError
  • RSS::NotValidXMLParser
  • RSS::NotWellFormedError
  • RSS::OverlappedPrefixError
  • RSS::Parser
  • RSS::RDF
  • RSS::RDF::Bag
  • RSS::RDF::Bag::Li
  • RSS::RDF::Channel
  • RSS::RDF::Channel::Image
  • RSS::RDF::Channel::Items
  • RSS::RDF::Channel::Items::Seq
  • RSS::RDF::Channel::Textinput
  • RSS::RDF::Image
  • RSS::RDF::Item
  • RSS::RDF::Li
  • RSS::RDF::Seq
  • RSS::RDF::Seq::Li
  • RSS::RDF::Textinput
  • RSS::REXMLLikeXMLParser
  • RSS::REXMLListener
  • RSS::REXMLParser
  • RSS::RSS09
  • RSS::RSS10
  • RSS::RootElementMixin
  • RSS::Rss
  • RSS::Rss::Channel
  • RSS::Rss::Channel::Cloud
  • RSS::Rss::Channel::Image
  • RSS::Rss::Channel::Item
  • RSS::Rss::Channel::Item::Category
  • RSS::Rss::Channel::Item::Enclosure
  • RSS::Rss::Channel::Item::Guid
  • RSS::Rss::Channel::Item::Source
  • RSS::Rss::Channel::SkipDays
  • RSS::Rss::Channel::SkipDays::Day
  • RSS::Rss::Channel::SkipHours
  • RSS::Rss::Channel::SkipHours::Hour
  • RSS::Rss::Channel::TextInput
  • RSS::SetupMaker
  • RSS::SlashModel
  • RSS::SyndicationModel
  • RSS::TaxonomyTopicModel
  • RSS::TaxonomyTopicModel::TaxonomyTopic
  • RSS::TaxonomyTopicsModel
  • RSS::TaxonomyTopicsModel::TaxonomyTopics
  • RSS::TaxonomyTopicsModel::TaxonomyTopics::Bag
  • RSS::TooMuchTagError
  • RSS::TrackBackModel10
  • RSS::TrackBackModel10::TrackBackAbout
  • RSS::TrackBackModel10::TrackBackPing
  • RSS::TrackBackModel20
  • RSS::TrackBackModel20::TrackBackAbout
  • RSS::TrackBackModel20::TrackBackPing
  • RSS::TrackBackUtils
  • RSS::UnknownConversionMethodError
  • RSS::UnknownConvertMethod
  • RSS::UnknownTagError
  • RSS::UnsupportedMakerVersionError
  • RSS::Utils
  • RSS::Utils::CSV
  • RSS::Utils::InheritedReader
  • RSS::Utils::YesCleanOther
  • RSS::Utils::YesOther
  • RSS::XML
  • RSS::XML::Element
  • RSS::XMLParserListener
  • RSS::XMLParserNotFound
  • RSS::XMLParserParser
  • RSS::XMLScanListener
  • RSS::XMLScanParser
  • RSS::XMLStyleSheet
  • RSS::XMLStyleSheetMixin
  • Gem::AvailableSet
  • Gem::Command
  • Gem::CommandLineError
  • Gem::CommandManager
  • Gem::Commands
  • Gem::Commands::BuildCommand
  • Gem::Commands::CertCommand
  • Gem::Commands::CheckCommand
  • Gem::Commands::CleanupCommand
  • Gem::Commands::ContentsCommand
  • Gem::Commands::DependencyCommand
  • Gem::Commands::EnvironmentCommand
  • Gem::Commands::FetchCommand
  • Gem::Commands::GenerateIndexCommand
  • Gem::Commands::HelpCommand
  • Gem::Commands::InstallCommand
  • Gem::Commands::ListCommand
  • Gem::Commands::LockCommand
  • Gem::Commands::MirrorCommand
  • Gem::Commands::OutdatedCommand
  • Gem::Commands::OwnerCommand
  • Gem::Commands::PristineCommand
  • Gem::Commands::PushCommand
  • Gem::Commands::QueryCommand
  • Gem::Commands::RdocCommand
  • Gem::Commands::SearchCommand
  • Gem::Commands::ServerCommand
  • Gem::Commands::SetupCommand
  • Gem::Commands::SourcesCommand
  • Gem::Commands::SpecificationCommand
  • Gem::Commands::StaleCommand
  • Gem::Commands::UninstallCommand
  • Gem::Commands::UnpackCommand
  • Gem::Commands::UpdateCommand
  • Gem::Commands::WhichCommand
  • Gem::Commands::YankCommand
  • Gem::ConfigFile
  • Gem::ConsoleUI
  • Gem::DefaultUserInteraction
  • Gem::Dependency
  • Gem::DependencyError
  • Gem::DependencyInstaller
  • Gem::DependencyList
  • Gem::DependencyRemovalException
  • Gem::DependencyResolutionError
  • Gem::DependencyResolver
  • Gem::DependencyResolver::APISet
  • Gem::DependencyResolver::APISpecification
  • Gem::DependencyResolver::ActivationRequest
  • Gem::DependencyResolver::CurrentSet
  • Gem::DependencyResolver::DependencyConflict
  • Gem::DependencyResolver::DependencyRequest
  • Gem::DependencyResolver::IndexSet
  • Gem::DependencyResolver::IndexSpecification
  • Gem::Deprecate
  • Gem::Doctor
  • Gem::DocumentError
  • Gem::EndOfYAMLException
  • Gem::ErrorReason
  • Gem::Exception
  • Gem::Ext
  • Gem::Ext::Builder
  • Gem::Ext::CmakeBuilder
  • Gem::Ext::ConfigureBuilder
  • Gem::Ext::ExtConfBuilder
  • Gem::Ext::RakeBuilder
  • Gem::FakeFetcher
  • Gem::FilePermissionError
  • Gem::FormatException
  • Gem::GemNotFoundException
  • Gem::GemNotInHomeException
  • Gem::GemRunner
  • Gem::GemcutterUtilities
  • Gem::ImpossibleDependenciesError
  • Gem::Indexer
  • Gem::InstallError
  • Gem::InstallUpdateOptions
  • Gem::Installer
  • Gem::Installer::ExtensionBuildError
  • Gem::InstallerTestCase
  • Gem::InvalidSpecificationException
  • Gem::LoadError
  • Gem::LocalRemoteOptions
  • Gem::MockGemUi
  • Gem::MockGemUi::InputEOFError
  • Gem::MockGemUi::SystemExitException
  • Gem::MockGemUi::TTY
  • Gem::MockGemUi::TermError
  • Gem::NameTuple
  • Gem::NoAliasYAMLTree
  • Gem::OperationNotSupportedError
  • Gem::Package
  • Gem::Package::DigestIO
  • Gem::Package::Error
  • Gem::Package::FormatError
  • Gem::Package::NonSeekableIO
  • Gem::Package::Old
  • Gem::Package::PathError
  • Gem::Package::TarHeader
  • Gem::Package::TarInvalidError
  • Gem::Package::TarReader
  • Gem::Package::TarReader::Entry
  • Gem::Package::TarReader::UnexpectedEOF
  • Gem::Package::TarTestCase
  • Gem::Package::TarWriter
  • Gem::Package::TarWriter::BoundedStream
  • Gem::Package::TarWriter::FileOverflow
  • Gem::Package::TarWriter::RestrictedStream
  • Gem::Package::TooLongFileName
  • Gem::PackageTask
  • Gem::PathSupport
  • Gem::Platform
  • Gem::PlatformMismatch
  • Gem::RemoteError
  • Gem::RemoteFetcher
  • Gem::RemoteFetcher::FetchError
  • Gem::RemoteFetcher::UnknownHostError
  • Gem::RemoteInstallationCancelled
  • Gem::RemoteInstallationSkipped
  • Gem::RemoteSourceException
  • Gem::RequestSet
  • Gem::RequestSet::GemDepedencyAPI
  • Gem::Requirement
  • Gem::Requirement::BadRequirementError
  • Gem::Security
  • Gem::Security::DIGEST_ALGORITHM
  • Gem::Security::Exception
  • Gem::Security::KEY_ALGORITHM
  • Gem::Security::Policy
  • Gem::Security::Signer
  • Gem::Security::TrustDir
  • Gem::Server
  • Gem::SilentUI
  • Gem::Source
  • Gem::Source::Local
  • Gem::Source::SpecificFile
  • Gem::SourceFetchProblem
  • Gem::SourceList
  • Gem::SpecFetcher
  • Gem::SpecificGemNotFoundException
  • Gem::Specification
  • Gem::StreamUI
  • Gem::StreamUI::SilentDownloadReporter
  • Gem::StreamUI::SilentProgressReporter
  • Gem::StreamUI::SimpleProgressReporter
  • Gem::StreamUI::VerboseDownloadReporter
  • Gem::StreamUI::VerboseProgressReporter
  • Gem::SystemExitException
  • Gem::TestCase
  • Gem::TestCase::StaticSet
  • Gem::Text
  • Gem::Uninstaller
  • Gem::UnsatisfiableDepedencyError
  • Gem::UserInteraction
  • Gem::Validator
  • Gem::VerificationError
  • Gem::Version
  • Gem::Version::Requirement
  • Gem::VersionOption
  • Net
  • Net::APOP
  • Net::APOPSession
  • Net::FTP
  • Net::HTTP
  • Net::HTTP
  • Net::HTTP::Copy
  • Net::HTTP::Delete
  • Net::HTTP::Get
  • Net::HTTP::Head
  • Net::HTTP::Lock
  • Net::HTTP::Mkcol
  • Net::HTTP::Move
  • Net::HTTP::Options
  • Net::HTTP::Patch
  • Net::HTTP::Post
  • Net::HTTP::Propfind
  • Net::HTTP::Proppatch
  • Net::HTTP::Put
  • Net::HTTP::Trace
  • Net::HTTP::Unlock
  • Net::HTTPAccepted
  • Net::HTTPBadGateway
  • Net::HTTPBadRequest
  • Net::HTTPClientError
  • Net::HTTPConflict
  • Net::HTTPContinue
  • Net::HTTPCreated
  • Net::HTTPError
  • Net::HTTPExceptions
  • Net::HTTPExpectationFailed
  • Net::HTTPFailedDependency
  • Net::HTTPFatalError
  • Net::HTTPForbidden
  • Net::HTTPFound
  • Net::HTTPFound
  • Net::HTTPGatewayTimeOut
  • Net::HTTPGenericRequest
  • Net::HTTPGone
  • Net::HTTPHeader
  • Net::HTTPInformation
  • Net::HTTPInformation::EXCEPTION_TYPE
  • Net::HTTPInsufficientStorage
  • Net::HTTPInternalServerError
  • Net::HTTPLengthRequired
  • Net::HTTPLocked
  • Net::HTTPMethodNotAllowed
  • Net::HTTPMovedPermanently
  • Net::HTTPMultiStatus
  • Net::HTTPMultipleChoices
  • Net::HTTPMultipleChoices
  • Net::HTTPNetworkAuthenticationRequired
  • Net::HTTPNoContent
  • Net::HTTPNonAuthoritativeInformation
  • Net::HTTPNotAcceptable
  • Net::HTTPNotFound
  • Net::HTTPNotImplemented
  • Net::HTTPNotModified
  • Net::HTTPOK
  • Net::HTTPPartialContent
  • Net::HTTPPaymentRequired
  • Net::HTTPPreconditionFailed
  • Net::HTTPPreconditionRequired
  • Net::HTTPProxyAuthenticationRequired
  • Net::HTTPRedirection
  • Net::HTTPRedirection::EXCEPTION_TYPE
  • Net::HTTPRequest
  • Net::HTTPRequestEntityTooLarge
  • Net::HTTPRequestHeaderFieldsTooLarge
  • Net::HTTPRequestTimeOut
  • Net::HTTPRequestURITooLong
  • Net::HTTPRequestURITooLong
  • Net::HTTPRequestedRangeNotSatisfiable
  • Net::HTTPResetContent
  • Net::HTTPResponse
  • Net::HTTPRetriableError
  • Net::HTTPSeeOther
  • Net::HTTPServerError
  • Net::HTTPServerException
  • Net::HTTPServiceUnavailable
  • Net::HTTPSuccess
  • Net::HTTPSuccess::EXCEPTION_TYPE
  • Net::HTTPSwitchProtocol
  • Net::HTTPTemporaryRedirect
  • Net::HTTPTooManyRequests
  • Net::HTTPUnauthorized
  • Net::HTTPUnknownResponse
  • Net::HTTPUnknownResponse::EXCEPTION_TYPE
  • Net::HTTPUnprocessableEntity
  • Net::HTTPUnsupportedMediaType
  • Net::HTTPUpgradeRequired
  • Net::HTTPUseProxy
  • Net::HTTPVersionNotSupported
  • Net::IMAP
  • Net::IMAP::BadResponseError
  • Net::IMAP::BodyTypeAttachment
  • Net::IMAP::BodyTypeBasic
  • Net::IMAP::BodyTypeExtension
  • Net::IMAP::BodyTypeMessage
  • Net::IMAP::BodyTypeMultipart
  • Net::IMAP::BodyTypeText
  • Net::IMAP::ByeResponseError
  • Net::IMAP::CramMD5Authenticator
  • Net::IMAP::DataFormatError
  • Net::IMAP::DigestMD5Authenticator
  • Net::IMAP::Error
  • Net::IMAP::FlagCountError
  • Net::IMAP::LoginAuthenticator
  • Net::IMAP::NoResponseError
  • Net::IMAP::PlainAuthenticator
  • Net::IMAP::ResponseError
  • Net::IMAP::ResponseParseError
  • Net::OpenTimeout
  • Net::POP3
  • Net::POPAuthenticationError
  • Net::POPBadResponse
  • Net::POPError
  • Net::POPMail
  • Net::ProtoAuthError
  • Net::ProtoCommandError
  • Net::ProtoFatalError
  • Net::ProtoRetriableError
  • Net::ProtoRetriableError
  • Net::ProtoServerError
  • Net::ProtoSyntaxError
  • Net::ProtoUnknownError
  • Net::ProtocolError
  • Net::ReadTimeout
  • Net::SMTP
  • Net::SMTP::Response
  • Net::SMTPAuthenticationError
  • Net::SMTPError
  • Net::SMTPFatalError
  • Net::SMTPServerBusy
  • Net::SMTPSyntaxError
  • Net::SMTPUnknownError
  • Net::SMTPUnsupportedCommand
  • Net::Telnet
  • Net::WriteAdapter
  • OpenSSL
  • OpenSSL::ASN1
  • OpenSSL::ASN1::ASN1Data
  • OpenSSL::ASN1::ASN1Error
  • OpenSSL::ASN1::Constructive
  • OpenSSL::ASN1::ObjectId
  • OpenSSL::ASN1::Primitive
  • OpenSSL::BN
  • OpenSSL::BNError
  • OpenSSL::Buffering
  • OpenSSL::Cipher
  • OpenSSL::Cipher::Cipher
  • OpenSSL::Cipher::CipherError
  • OpenSSL::Config
  • OpenSSL::ConfigError
  • OpenSSL::Digest
  • OpenSSL::Digest::Digest
  • OpenSSL::Digest::DigestError
  • OpenSSL::Engine
  • OpenSSL::Engine::EngineError
  • OpenSSL::HMAC
  • OpenSSL::HMACError
  • OpenSSL::Netscape
  • OpenSSL::Netscape::SPKI
  • OpenSSL::Netscape::SPKIError
  • OpenSSL::OCSP
  • OpenSSL::OCSP::BasicResponse
  • OpenSSL::OCSP::CertificateId
  • OpenSSL::OCSP::OCSPError
  • OpenSSL::OCSP::Request
  • OpenSSL::OCSP::Response
  • OpenSSL::OpenSSLError
  • OpenSSL::PKCS12
  • OpenSSL::PKCS12::PKCS12Error
  • OpenSSL::PKCS5
  • OpenSSL::PKCS5::PKCS5Error
  • OpenSSL::PKCS7
  • OpenSSL::PKCS7::PKCS7Error
  • OpenSSL::PKCS7::RecipientInfo
  • OpenSSL::PKCS7::SignerInfo
  • OpenSSL::PKey
  • OpenSSL::PKey::DH
  • OpenSSL::PKey::DHError
  • OpenSSL::PKey::DSA
  • OpenSSL::PKey::DSAError
  • OpenSSL::PKey::EC
  • OpenSSL::PKey::EC::Group
  • OpenSSL::PKey::EC::Group::Error
  • OpenSSL::PKey::EC::Point
  • OpenSSL::PKey::EC::Point::Error
  • OpenSSL::PKey::ECError
  • OpenSSL::PKey::PKey
  • OpenSSL::PKey::PKeyError
  • OpenSSL::PKey::RSA
  • OpenSSL::PKey::RSAError
  • OpenSSL::Random
  • OpenSSL::Random::RandomError
  • OpenSSL::SSL
  • OpenSSL::SSL::Nonblock
  • OpenSSL::SSL::SSLContext
  • OpenSSL::SSL::SSLError
  • OpenSSL::SSL::SSLServer
  • OpenSSL::SSL::SSLSocket
  • OpenSSL::SSL::Session
  • OpenSSL::SSL::Session::SessionError
  • OpenSSL::SSL::SocketForwarder
  • OpenSSL::X509
  • OpenSSL::X509::Attribute
  • OpenSSL::X509::AttributeError
  • OpenSSL::X509::CRL
  • OpenSSL::X509::CRLError
  • OpenSSL::X509::Certificate
  • OpenSSL::X509::CertificateError
  • OpenSSL::X509::Extension
  • OpenSSL::X509::ExtensionError
  • OpenSSL::X509::ExtensionFactory
  • OpenSSL::X509::Name
  • OpenSSL::X509::Name::RFC2253DN
  • OpenSSL::X509::NameError
  • OpenSSL::X509::Request
  • OpenSSL::X509::RequestError
  • OpenSSL::X509::Revoked
  • OpenSSL::X509::RevokedError
  • OpenSSL::X509::Store
  • OpenSSL::X509::StoreContext
  • OpenSSL::X509::StoreError
  • REXML
  • REXML::AttlistDecl
  • REXML::Attribute
  • REXML::Attributes
  • REXML::CData
  • REXML::Child
  • REXML::Comment
  • REXML::DTD
  • REXML::DTD::AttlistDecl
  • REXML::DTD::ElementDecl
  • REXML::DTD::EntityDecl
  • REXML::DTD::NotationDecl
  • REXML::DTD::Parser
  • REXML::Declaration
  • REXML::DocType
  • REXML::Document
  • REXML::Element
  • REXML::ElementDecl
  • REXML::Elements
  • REXML::Encoding
  • REXML::Entity
  • REXML::EntityConst
  • REXML::ExternalEntity
  • REXML::Formatters
  • REXML::Formatters::Default
  • REXML::Formatters::Pretty
  • REXML::Formatters::Transitive
  • REXML::Functions
  • REXML::IOSource
  • REXML::Instruction
  • REXML::Light
  • REXML::Light::Node
  • REXML::Namespace
  • REXML::Node
  • REXML::NotationDecl
  • REXML::Output
  • REXML::Parent
  • REXML::ParseException
  • REXML::Parsers
  • REXML::Parsers::BaseParser
  • REXML::Parsers::LightParser
  • REXML::Parsers::PullEvent
  • REXML::Parsers::PullParser
  • REXML::Parsers::SAX2Parser
  • REXML::Parsers::StreamParser
  • REXML::Parsers::TreeParser
  • REXML::Parsers::UltraLightParser
  • REXML::Parsers::XPathParser
  • REXML::QuickPath
  • REXML::SAX2Listener
  • REXML::Source
  • REXML::SourceFactory
  • REXML::StreamListener
  • REXML::SyncEnumerator
  • REXML::Text
  • REXML::UndefinedNamespaceException
  • REXML::Validation
  • REXML::Validation::Choice
  • REXML::Validation::Event
  • REXML::Validation::Interleave
  • REXML::Validation::OneOrMore
  • REXML::Validation::Optional
  • REXML::Validation::Ref
  • REXML::Validation::RelaxNG
  • REXML::Validation::Sequence
  • REXML::Validation::State
  • REXML::Validation::ValidationException
  • REXML::Validation::Validator
  • REXML::Validation::ZeroOrMore
  • REXML::XMLDecl
  • REXML::XMLTokens
  • REXML::XPath
  • REXML::XPathParser
  • WEBrick
  • WEBrick::AccessLog
  • WEBrick::AccessLog::AccessLogError
  • WEBrick::BasicLog
  • WEBrick::CGI
  • WEBrick::Config
  • WEBrick::Cookie
  • WEBrick::Daemon
  • WEBrick::GenericServer
  • WEBrick::HTMLUtils
  • WEBrick::HTTPAuth
  • WEBrick::HTTPAuth::Authenticator
  • WEBrick::HTTPAuth::BasicAuth
  • WEBrick::HTTPAuth::DigestAuth
  • WEBrick::HTTPAuth::Htdigest
  • WEBrick::HTTPAuth::Htgroup
  • WEBrick::HTTPAuth::Htpasswd
  • WEBrick::HTTPAuth::ProxyAuthenticator
  • WEBrick::HTTPAuth::ProxyBasicAuth
  • WEBrick::HTTPAuth::ProxyDigestAuth
  • WEBrick::HTTPAuth::UserDB
  • WEBrick::HTTPProxyServer
  • WEBrick::HTTPRequest
  • WEBrick::HTTPResponse
  • WEBrick::HTTPServer
  • WEBrick::HTTPServerError
  • WEBrick::HTTPServlet
  • WEBrick::HTTPServlet::AbstractServlet
  • WEBrick::HTTPServlet::CGIHandler
  • WEBrick::HTTPServlet::DefaultFileHandler
  • WEBrick::HTTPServlet::ERBHandler
  • WEBrick::HTTPServlet::FileHandler
  • WEBrick::HTTPServlet::HTTPServletError
  • WEBrick::HTTPServlet::ProcHandler
  • WEBrick::HTTPStatus
  • WEBrick::HTTPStatus::ClientError
  • WEBrick::HTTPStatus::EOFError
  • WEBrick::HTTPStatus::Error
  • WEBrick::HTTPStatus::Info
  • WEBrick::HTTPStatus::Redirect
  • WEBrick::HTTPStatus::ServerError
  • WEBrick::HTTPStatus::Status
  • WEBrick::HTTPStatus::Success
  • WEBrick::HTTPUtils
  • WEBrick::HTTPUtils::FormData
  • WEBrick::HTTPVersion
  • WEBrick::Log
  • WEBrick::ServerError
  • WEBrick::SimpleServer
  • WEBrick::Utils
  • WEBrick::Utils::TimeoutHandler
  • IRB::Abort
  • IRB::Context
  • IRB::ContextExtender
  • IRB::ExtendCommandBundle
  • IRB::FileInputMethod
  • IRB::Frame
  • IRB::InputMethod
  • IRB::Inspector
  • IRB::Irb
  • IRB::IrbLoader
  • IRB::JobManager
  • IRB::LoadAbort
  • IRB::MethodExtender
  • IRB::Notifier
  • IRB::Notifier::AbstractNotifier
  • IRB::Notifier::CompositeNotifier
  • IRB::Notifier::LeveledNotifier
  • IRB::Notifier::NoMsgNotifier
  • IRB::OutputMethod
  • IRB::ReadlineInputMethod
  • IRB::StdioInputMethod
  • IRB::StdioOutputMethod
  • IRB::WorkSpace
  • Rake::AltSystem
  • Rake::Application
  • Rake::Application
  • Rake::Backtrace
  • Rake::Cloneable
  • Rake::CompositePublisher
  • Rake::DSL
  • Rake::DefaultLoader
  • Rake::EarlyTime
  • Rake::FileCreationTask
  • Rake::FileList
  • Rake::FileList
  • Rake::FileTask
  • Rake::FileUtilsExt
  • Rake::FileUtilsExt
  • Rake::FtpFile
  • Rake::FtpUploader
  • Rake::InvocationChain
  • Rake::InvocationChain::EmptyInvocationChain
  • Rake::InvocationExceptionMixin
  • Rake::MakefileLoader
  • Rake::MultiTask
  • Rake::NameSpace
  • Rake::PackageTask
  • Rake::PrivateReader
  • Rake::PseudoStatus
  • Rake::RubyForgePublisher
  • Rake::RuleRecursionOverflowError
  • Rake::SshDirPublisher
  • Rake::SshFilePublisher
  • Rake::SshFreshDirPublisher
  • Rake::Task
  • Rake::TaskArgumentError
  • Rake::TaskArguments
  • Rake::TaskLib
  • Rake::TaskManager
  • Rake::TestTask
  • Rake::TraceOutput
  • Rake::Win32
  • Rake::Win32::Win32HomeError
  • XMLRPC
  • XMLRPC::Base64
  • XMLRPC::BasicServer
  • XMLRPC::CGIServer
  • XMLRPC::Client
  • XMLRPC::Client::Proxy
  • XMLRPC::Config
  • XMLRPC::Convert
  • XMLRPC::Create
  • XMLRPC::DateTime
  • XMLRPC::FaultException
  • XMLRPC::Marshal
  • XMLRPC::Marshallable
  • XMLRPC::ModRubyServer
  • XMLRPC::ParseContentType
  • XMLRPC::ParserWriterChooseMixin
  • XMLRPC::Server
  • XMLRPC::Service
  • XMLRPC::Service::BasicInterface
  • XMLRPC::Service::Interface
  • XMLRPC::Service::PublicInstanceMethodsInterface
  • XMLRPC::WEBrickServlet
  • XMLRPC::XMLParser
  • XMLRPC::XMLParser::AbstractStreamParser
  • XMLRPC::XMLParser::AbstractTreeParser
  • XMLRPC::XMLParser::NQXMLParser
  • XMLRPC::XMLParser::NQXMLStreamParser
  • XMLRPC::XMLParser::NQXMLStreamParser::XMLRPCParser
  • XMLRPC::XMLParser::NQXMLTreeParser
  • XMLRPC::XMLParser::REXMLStreamParser
  • XMLRPC::XMLParser::REXMLStreamParser::StreamListener
  • XMLRPC::XMLParser::StreamParserMixin
  • XMLRPC::XMLParser::XMLParser
  • XMLRPC::XMLParser::XMLScanStreamParser
  • XMLRPC::XMLParser::XMLScanStreamParser::XMLScanParser
  • XMLRPC::XMLParser::XMLStreamParser
  • XMLRPC::XMLParser::XMLTreeParser
  • XMLRPC::XMLWriter
  • XMLRPC::XMLWriter::Abstract
  • XMLRPC::XMLWriter::Simple
  • XMLRPC::XMLWriter::XMLParser
  • Psych
  • Psych::BadAlias
  • Psych::Coder
  • Psych::Error
  • Psych::Exception
  • Psych::Handler
  • Psych::Handler::DumperOptions
  • Psych::Handlers
  • Psych::Handlers::Recorder
  • Psych::JSON
  • Psych::JSON::Stream
  • Psych::JSON::TreeBuilder
  • Psych::Nodes
  • Psych::Nodes::Alias
  • Psych::Nodes::Document
  • Psych::Nodes::Mapping
  • Psych::Nodes::Node
  • Psych::Nodes::Scalar
  • Psych::Nodes::Sequence
  • Psych::Nodes::Stream
  • Psych::Omap
  • Psych::Parser
  • Psych::Parser::Mark
  • Psych::PrivateType
  • Psych::ScalarScanner
  • Psych::Set
  • Psych::Stream
  • Psych::Streaming
  • Psych::SyntaxError
  • Psych::TreeBuilder
  • Psych::Visitors
  • Psych::Visitors::DepthFirst
  • Psych::Visitors::Emitter
  • Psych::Visitors::JSONTree
  • Psych::Visitors::ToRuby
  • Psych::Visitors::Visitor
  • Psych::Visitors::YAMLTree
  • Resolv
  • Resolv::DNS
  • Resolv::DNS::Config
  • Resolv::DNS::Config::NXDomain
  • Resolv::DNS::Config::OtherResolvError
  • Resolv::DNS::DecodeError
  • Resolv::DNS::EncodeError
  • Resolv::DNS::Name
  • Resolv::DNS::Query
  • Resolv::DNS::Requester
  • Resolv::DNS::Requester::RequestError
  • Resolv::DNS::Resource
  • Resolv::DNS::Resource::ANY
  • Resolv::DNS::Resource::CNAME
  • Resolv::DNS::Resource::DomainName
  • Resolv::DNS::Resource::Generic
  • Resolv::DNS::Resource::HINFO
  • Resolv::DNS::Resource::IN
  • Resolv::DNS::Resource::IN::A
  • Resolv::DNS::Resource::IN::AAAA
  • Resolv::DNS::Resource::IN::SRV
  • Resolv::DNS::Resource::IN::WKS
  • Resolv::DNS::Resource::MINFO
  • Resolv::DNS::Resource::MX
  • Resolv::DNS::Resource::NS
  • Resolv::DNS::Resource::PTR
  • Resolv::DNS::Resource::SOA
  • Resolv::DNS::Resource::TXT
  • Resolv::Hosts
  • Resolv::IPv4
  • Resolv::IPv6
  • Resolv::ResolvError
  • Resolv::ResolvTimeout
  • DRb
  • DRb::DRbArray
  • DRb::DRbBadScheme
  • DRb::DRbBadURI
  • DRb::DRbConn
  • DRb::DRbConnError
  • DRb::DRbError
  • DRb::DRbIdConv
  • DRb::DRbIdConv
  • DRb::DRbMessage
  • DRb::DRbObject
  • DRb::DRbObject
  • DRb::DRbObservable
  • DRb::DRbProtocol
  • DRb::DRbRemoteError
  • DRb::DRbSSLSocket
  • DRb::DRbSSLSocket::SSLConfig
  • DRb::DRbServer
  • DRb::DRbServerNotFound
  • DRb::DRbTCPSocket
  • DRb::DRbUNIXSocket
  • DRb::DRbUndumped
  • DRb::DRbUndumped
  • DRb::DRbUnknown
  • DRb::DRbUnknownError
  • DRb::ExtServ
  • DRb::ExtServManager
  • DRb::GW
  • DRb::GWIdConv
  • DRb::TimerIdConv
  • DRb::TimerIdConv::TimerHolder2
  • DRb::TimerIdConv::TimerHolder2::InvalidIndexError
  • DL
  • DL::BasicTypes
  • DL::CFunc
  • DL::CParser
  • DL::CPtr
  • DL::CStruct
  • DL::CStructBuilder
  • DL::CStructEntity
  • DL::CUnion
  • DL::CUnionEntity
  • DL::CarriedFunction
  • DL::CompositeHandler
  • DL::DLError
  • DL::DLTypeError
  • DL::Function
  • DL::Handle
  • DL::Importer
  • DL::PackInfo
  • DL::Packer
  • DL::Stack
  • DL::TempFunction
  • DL::ValueUtil
  • DL::Win32Types
  • OptionParser
  • OptionParser::AC
  • OptionParser::Acceptables
  • OptionParser::AmbiguousArgument
  • OptionParser::AmbiguousOption
  • OptionParser::Arguable
  • OptionParser::CompletingHash
  • OptionParser::Completion
  • OptionParser::InvalidArgument
  • OptionParser::InvalidOption
  • OptionParser::List
  • OptionParser::MissingArgument
  • OptionParser::NeedlessArgument
  • OptionParser::OptionMap
  • OptionParser::ParseError
  • OptionParser::Switch
  • OptionParser::Switch::NoArgument
  • OptionParser::Switch::OptionalArgument
  • OptionParser::Switch::PlacedArgument
  • OptionParser::Switch::RequiredArgument
  • Rinda
  • Rinda::DRbObjectTemplate
  • Rinda::InvalidHashTupleKey
  • Rinda::NotifyTemplateEntry
  • Rinda::RequestCanceledError
  • Rinda::RequestExpiredError
  • Rinda::RindaError
  • Rinda::RingFinger
  • Rinda::RingProvider
  • Rinda::RingServer
  • Rinda::SimpleRenewer
  • Rinda::Template
  • Rinda::TemplateEntry
  • Rinda::Tuple
  • Rinda::TupleBag
  • Rinda::TupleBag::TupleBin
  • Rinda::TupleEntry
  • Rinda::TupleSpace
  • Rinda::TupleSpaceProxy
  • Rinda::WaitTemplateEntry
  • Zlib
  • Zlib::BufError
  • Zlib::DataError
  • Zlib::Deflate
  • Zlib::Error
  • Zlib::GzipFile
  • Zlib::GzipFile::CRCError
  • Zlib::GzipFile::Error
  • Zlib::GzipFile::LengthError
  • Zlib::GzipFile::NoFooter
  • Zlib::GzipReader
  • Zlib::GzipWriter
  • Zlib::Inflate
  • Zlib::MemError
  • Zlib::NeedDict
  • Zlib::StreamEnd
  • Zlib::StreamError
  • Zlib::VersionError
  • Zlib::ZStream
  • Fiddle
  • Fiddle::BasicTypes
  • Fiddle::CParser
  • Fiddle::CStruct
  • Fiddle::CStructBuilder
  • Fiddle::CStructEntity
  • Fiddle::CUnion
  • Fiddle::CUnionEntity
  • Fiddle::Closure
  • Fiddle::Closure::BlockCaller
  • Fiddle::CompositeHandler
  • Fiddle::DLError
  • Fiddle::Function
  • Fiddle::Handle
  • Fiddle::Importer
  • Fiddle::Pointer
  • Fiddle::Win32Types
  • Test
  • Test::Unit
  • Test::Unit::Assertions
  • Test::Unit::AutoRunner
  • Test::Unit::AutoRunner::Runner
  • Test::Unit::GCStressOption
  • Test::Unit::GlobOption
  • Test::Unit::LoadPathOption
  • Test::Unit::Options
  • Test::Unit::ProxyError
  • Test::Unit::RequireFiles
  • Test::Unit::RunCount
  • Test::Unit::Runner
  • Test::Unit::Runner::Worker
  • Test::Unit::StatusLineOutput
  • Test::Unit::TestCase
  • Test::Unit::Worker
  • Win32
  • Win32::Registry
  • Win32::Registry::API
  • Win32::Registry::Constants
  • Win32::Registry::Error
  • Win32::Registry::Error::Kernel32
  • Win32::Registry::PredefinedKey
  • Win32::Resolv
  • Win32::Resolv::Kernel32
  • Win32::SSPI
  • Win32::SSPI::API
  • Win32::SSPI::Identity
  • Win32::SSPI::NegotiateAuth
  • Win32::SSPI::SSPIResult
  • Win32::SSPI::SecurityBuffer
  • Win32::SSPI::SecurityHandle
  • Win32::SSPI::TimeStamp
  • URI
  • URI::BadURIError
  • URI::Error
  • URI::Escape
  • URI::FTP
  • URI::Generic
  • URI::HTTP
  • URI::HTTPS
  • URI::InvalidComponentError
  • URI::InvalidURIError
  • URI::LDAP
  • URI::LDAPS
  • URI::MailTo
  • URI::Parser
  • URI::REGEXP
  • URI::REGEXP::PATTERN
  • MiniTest
  • MiniTest::Assertion
  • MiniTest::Assertions
  • MiniTest::Expectations
  • MiniTest::Mock
  • MiniTest::Skip
  • MiniTest::Spec
  • MiniTest::Unit
  • MiniTest::Unit::Deprecated
  • MiniTest::Unit::Deprecated::Hooks
  • MiniTest::Unit::Deprecated::HooksCM
  • MiniTest::Unit::Guard
  • MiniTest::Unit::LifecycleHooks
  • MiniTest::Unit::TestCase
  • Shell
  • Shell::AppendFile
  • Shell::AppendIO
  • Shell::BuiltInCommand
  • Shell::Cat
  • Shell::CommandProcessor
  • Shell::Concat
  • Shell::Echo
  • Shell::Error
  • Shell::Filter
  • Shell::Glob
  • Shell::ProcessController
  • Shell::SystemCommand
  • Shell::Tee
  • Shell::Void
  • CGI
  • CGI::Cookie
  • CGI::HtmlExtension
  • CGI::InvalidEncoding
  • CGI::QueryExtension
  • CGI::Session
  • CGI::Session::FileStore
  • CGI::Session::MemoryStore
  • CGI::Session::NullStore
  • CGI::Session::PStore
  • JSON
  • JSON::Ext
  • JSON::GeneratorError
  • JSON::GenericObject
  • JSON::JSONError
  • JSON::MissingUnicodeSupport
  • JSON::NestingError
  • JSON::ParserError
  • JSON::UnparserError
  • Digest
  • Digest::Base
  • Digest::Class
  • Digest::HMAC
  • Digest::Instance
  • Digest::MD5
  • Digest::RMD160
  • Digest::SHA1
  • Prime
  • Prime::EratosthenesGenerator
  • Prime::EratosthenesSieve
  • Prime::Generator23
  • Prime::OldCompatibility
  • Prime::PseudoPrimeGenerator
  • Prime::TrialDivision
  • Prime::TrialDivisionGenerator
  • Syslog
  • Syslog::Constants
  • Syslog::Facility
  • Syslog::Level
  • Syslog::Logger
  • Syslog::Logger::Formatter
  • Syslog::Macros
  • Syslog::Option
  • YAML::DBM
  • YAML::Store
  • FileUtils
  • FileUtils::DryRun
  • FileUtils::LowMethods
  • FileUtils::NoWrite
  • FileUtils::StreamUtils_
  • FileUtils::Verbose
  • GetoptLong
  • GetoptLong::AmbiguousOption
  • GetoptLong::Error
  • GetoptLong::InvalidOption
  • GetoptLong::MissingArgument
  • GetoptLong::NeedlessArgument
  • Logger
  • Logger::Application
  • Logger::Formatter
  • Logger::LogDevice
  • Logger::LogDevice::LogDeviceMutex
  • Logger::Severity
  • Object
  • Object::ParseError
  • Object::Synchronizer
  • Object::Synchronizer_m
  • Object::ThWait
  • Object::TimeoutError
  • PrettyPrint
  • PrettyPrint::Breakable
  • PrettyPrint::Group
  • PrettyPrint::GroupQueue
  • PrettyPrint::SingleLine
  • PrettyPrint::Text
  • Curses
  • Curses::Key
  • Curses::MouseEvent
  • Curses::Pad
  • Curses::Window
  • IPAddr
  • IPAddr::AddressFamilyError
  • IPAddr::Error
  • IPAddr::InvalidAddressError
  • IPAddr::InvalidPrefixError
  • OpenURI
  • OpenURI::HTTPError
  • OpenURI::HTTPRedirect
  • OpenURI::Meta
  • OpenURI::OpenRead
  • Racc
  • Racc::CparseParams
  • Racc::ParseError
  • Racc::ParseError
  • Racc::Parser
  • Sync_m
  • Sync_m
  • Sync_m::Err
  • Sync_m::Err::LockModeFailer
  • Sync_m::Err::UnknownLocker
  • CSV
  • CSV::MalformedCSVError
  • CSV::Row
  • CSV::Table
  • Errno
  • Errno::ECONNABORTED
  • Errno::ECONNRESET
  • Errno::EPROTO
  • HttpServer
  • HttpServer::Request
  • HttpServer::Response
  • HttpServer::Table
  • PP
  • PP::ObjectMixin
  • PP::PPMethods
  • PP::SingleLine
  • Socket
  • Socket::AncillaryData
  • Socket::Option
  • Socket::UDPSource
  • ACL
  • ACL::ACLEntry
  • ACL::ACLList
  • ERB
  • ERB::DefMethod
  • ERB::Util
  • IO
  • IO::readable
  • IO::writable
  • MakeMakefile
  • Matrix
  • Matrix::EigenvalueDecomposition
  • Matrix::LUPDecomposition
  • MonitorMixin
  • MonitorMixin::ConditionVariable
  • MonitorMixin::ConditionVariable::Timeout
  • Scanf
  • Timeout
  • Timeout::Error
  • Timeout::Error
  • Benchmark
  • Benchmark::Tms
  • Exception2MessageMapper
  • Exception2MessageMapper::E2MM
  • File
  • File::Stat
  • Minitest
  • Minitest::Unit
  • NQXML
  • NQXML::Node
  • PStore
  • PStore::Error
  • PTY
  • PTY::ChildExited
  • Ripper
  • Ripper::Filter
  • StringScanner
  • StringScanner::Error
  • Sync
  • Sync
  • TSort
  • TSort::Cyclic
  • Tempfile
  • ThreadsWait
  • ThreadsWait
  • Vector
  • Vector::ZeroVectorError
  • WIN32OLE
  • WIN32OLE::VARIANT
  • WeakRef
  • WeakRef::RefError
  • XML
  • XML::Parser
  • XMLEncoding_ja
  • XMLEncoding_ja::SJISHandler
  • XMP
  • XMP::StringInputMethod
  • Abbrev
  • Addrinfo
  • Base64
  • BasicSocket
  • BigDecimal
  • BigMath
  • CMath
  • Class
  • Complex
  • CompositePublisher
  • ConditionVariable
  • Coverage
  • DBM
  • DBMError
  • DEBUGGER__
  • DateTime
  • Delegator
  • Dir
  • ENV
  • English
  • Enumerable
  • Etc
  • Exception
  • Fcntl
  • Find
  • Float
  • Forwardable
  • GDBM
  • GDBMError
  • GDBMFatalError
  • GServer
  • Hash
  • IPSocket
  • Integer
  • Jacobian
  • Kconv
  • Kernel
  • LUSolve
  • MatchData
  • Math
  • Module
  • Monitor
  • Mutex_m
  • NKF
  • Newton
  • Numeric
  • OLEProperty
  • Observable
  • Open3
  • OpenStruct
  • ParallelEach
  • Pathname
  • PrideIO
  • PrideLOL
  • Profiler__
  • Queue
  • Range
  • Rational
  • Readline
  • Regexp
  • SDBM
  • SDBMError
  • SOCKSSocket
  • SecureRandom
  • Set
  • Shellwords
  • SimpleDelegator
  • SingleForwardable
  • Singleton
  • SizedQueue
  • SocketError
  • SortedSet
  • SshDirPublisher
  • SshFilePublisher
  • SshFreshDirPublisher
  • StringIO
  • Struct
  • Symbol
  • Sys
  • TCPServer
  • TCPSocket
  • TempIO
  • ThreadError
  • Time
  • Tracer
  • UDPSocket
  • UNIXServer
  • UNIXSocket
  • WIN32OLERuntimeError
  • WIN32OLE_EVENT
  • WIN32OLE_METHOD
  • WIN32OLE_PARAM
  • WIN32OLE_TYPE
  • WIN32OLE_TYPELIB
  • WIN32OLE_VARIABLE
  • WIN32OLE_VARIANT
  • Win32API